Skip to content

Commit

Permalink
feat: cmd-update #8
Browse files Browse the repository at this point in the history
  • Loading branch information
midnqp committed Mar 9, 2023
1 parent c591f51 commit 2e970e6
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 79 deletions.
123 changes: 65 additions & 58 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,60 +1,67 @@
{
"name": "pcli",
"type": "module",
"scripts": {
"test:backend": "npx ts-node-esm test/server.ts",
"build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
"build:bin": "npm run build && npm run prepack:esbuild:cjs && npm run prepack:pkg",
"build:bin:all": "npm run build && npm run prepack:esbuild:cjs && npm run prepack:pkg:all",
"dev": "tsc-watch --noClear -p tsconfig.json",
"prepack:webpack": "npx webpack --config webpack.config.cjs",
"prepack:pkg:all": "npx pkg --options 'no-warnings' -t node18-linux-x64,node18-macos-x64,node18-win-x64 ./dist/bundle.cjs -o ./bin/pcli",
"prepack:pkg": "npx pkg --options 'no-warnings' -t node18 ./dist/bundle.cjs -o ./bin/pcli",
"prepack:esbuild:cjs": "npx esbuild dist/src/index.js --bundle --outfile=dist/bundle.cjs --format=cjs --platform=node",
"prepack:esbuild:esm": "npx esbuild dist/src/index.js --bundle --outfile=dist/bundle.mjs --format=esm --platform=node --banner:js=\"import {createRequire} from 'module'; const require = createRequire(import.meta.url); import { dirname } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url));\""
},
"dependencies": {
"axios": "^0.27.2",
"browserify": "^17.0.0",
"chai": "^4.3.7",
"chalk": "^5.2.0",
"clean-stack": "^5.1.0",
"commander": "^9.4.0",
"content-type": "^1.0.4",
"dotenv": "^16.0.1",
"enquirer": "^2.3.6",
"fs-extra": "^11.1.0",
"lodash": "^4.17.21",
"newman": "^5.3.2",
"postman-collection": "^4.1.5",
"pretty-bytes": "^6.1.0",
"terser": "^5.16.5",
"uuid": "^9.0.0",
"winston": "^3.8.2"
},
"devDependencies": {
"@babel/cli": "^7.18.10",
"@babel/core": "^7.18.10",
"@inquirer/editor": "^0.0.21-alpha.0",
"@types/chai": "^4.3.4",
"@types/content-type": "^1.1.5",
"@types/express": "^4.17.17",
"@types/fs-extra": "^9.0.13",
"@types/lodash": "^4.14.182",
"@types/newman": "^5.3.1",
"@types/postman-collection": "^3.5.7",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"eslint": "^8.33.0",
"express": "^4.18.2",
"pkg": "^5.8.0",
"ts-node": "^10.9.1",
"tsc-alias": "^1.8.2",
"tsc-watch": "^5.0.3",
"typescript": "^4.7.4"
},
"bundleDependencies": [
"terser"
]
"name": "pcli",
"type": "module",
"main": "./src/index.js",
"scripts": {
"test:backend": "npx ts-node-esm test/server.ts",
"build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
"build:bin": "npm run build && npm run prepack:esbuild:cjs && npm run prepack:pkg",
"build:bin:all": "npm run build && npm run prepack:esbuild:cjs && npm run prepack:pkg:all",
"dev": "tsc-watch --noClear -p tsconfig.json",
"prepack:webpack": "npx webpack --config webpack.config.cjs",
"prepack:pkg:all": "npx pkg --options 'no-warnings' -t node18-linux-x64,node18-macos-x64,node18-win-x64 ./dist/bundle.cjs -o ./bin/pcli",
"prepack:pkg": "npx pkg --options 'no-warnings' -t node18 ./dist/bundle.cjs -o ./bin/pcli",
"prepack:esbuild:cjs": "npx esbuild dist/src/index.js --bundle --outfile=dist/bundle.cjs --format=cjs --platform=node",
"prepack:esbuild:esm": "npx esbuild dist/src/index.js --bundle --outfile=dist/bundle.mjs --format=esm --platform=node --banner:js=\"import {createRequire} from 'module'; const require = createRequire(import.meta.url); import { dirname } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url));\""
},
"dependencies": {
"axios": "^0.27.2",
"browserify": "^17.0.0",
"chai": "^4.3.7",
"chalk": "^5.2.0",
"clean-stack": "^5.1.0",
"commander": "^9.4.0",
"content-type": "^1.0.4",
"dotenv": "^16.0.1",
"enquirer": "^2.3.6",
"fs-extra": "^11.1.0",
"js-object-pretty-print": "^0.3.0",
"lodash": "^4.17.21",
"newman": "^5.3.2",
"postman-collection": "^4.1.5",
"pretty-bytes": "^6.1.0",
"terser": "^5.16.5",
"tmp": "^0.2.1",
"uuid": "^9.0.0",
"winston": "^3.8.2"
},
"devDependencies": {
"@babel/cli": "^7.18.10",
"@babel/core": "^7.18.10",
"@inquirer/editor": "^0.0.21-alpha.0",
"@types/chai": "^4.3.4",
"@types/content-type": "^1.1.5",
"@types/express": "^4.17.17",
"@types/fs-extra": "^9.0.13",
"@types/lodash": "^4.14.182",
"@types/newman": "^5.3.1",
"@types/postman-collection": "^3.5.7",
"@types/tmp": "^0.2.3",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.1",
"esbuild": "^0.17.11",
"eslint": "^8.33.0",
"express": "^4.18.2",
"open": "^8.4.2",
"open-editor": "^4.0.0",
"pkg": "^5.8.0",
"ts-node": "^10.9.1",
"tsc-alias": "^1.8.2",
"tsc-watch": "^5.0.3",
"typescript": "^4.7.4"
},
"bundleDependencies": [
"terser"
]
}
101 changes: 93 additions & 8 deletions src/handlers/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@ import services from '@src/services/index.js'
import psdk from 'postman-collection'
import { PostmanCli } from '@src/types'
import { Command } from 'commander'
import editor from '@inquirer/editor'
import util from 'node:util'
import _ from 'lodash'
import Enquirer from 'enquirer'
import openeditor from 'open-editor'
import editor from '@inquirer/editor'
import open from 'open'
import tmp from 'tmp'
import fs from 'node:fs'

function openJson(input: string) {
const { name } = tmp.fileSync({ postfix: '.js' })
fs.writeFileSync(name, input)

//openeditor([{file: name}])
open(name)
return name
}

export default async function (
args: PostmanCli.Cmd.VariadicResources,
Expand All @@ -15,20 +30,90 @@ export default async function (
const resource = services.resource.getFromNested(co, args)

if (services.response.isResponse(resource)) {
const p = services.example.toPrintable(resource)
const p = services.example.toPrintable(resource, {
addParsedBody: true,
})

const str = util.inspect(p, {
colors: false,
maxArrayLength: null,
maxStringLength: null,
depth: 50,
})
const prompt: any = await editor({ default: str, message: '' })
//const prompt = await editor({default: str, message: ''})
const filename = openJson(str)
let done: boolean
try {
const enq = (await Enquirer.prompt({
name: 'done',
required: true,
initial: true,
message: 'press any key to continue',
type: 'confirm',
})) as any
done = enq.done
} catch (err) {
done = false
}

new psdk.Response({
code: prompt.response.code,
responseTime: prompt.response.time,
body: prompt.response.body,
header: [{}],
if (!done) return

type ParsedPrompt = {
request: PostmanCli.RequestPrintable
response: PostmanCli.ResponsePrintable
}
let prompt: ParsedPrompt
try {
prompt = eval(
'(' + (await fs.promises.readFile(filename, 'utf8')) + ')'
)
} catch (e) {
throw Error('could not parse')
}
const parsed = prompt

let request: psdk.RequestDefinition | undefined
if (parsed.request && !_.isEmpty(parsed.request)) {
const rawBody = JSON.stringify(parsed.request.body)
request = {
url: {
path: parsed.request.url.path,
query: services.common.jsonToHeaders(parsed.request.query),
},
body: { mode: 'raw', raw: rawBody },
header: services.common.jsonToHeaders(parsed.request.headers),
method: parsed.request.url.method,
}
}
const response = new psdk.Response({
code: parsed.response.code,
responseTime: parsed.response.time,
body: JSON.stringify(parsed.response.body),
header: services.common.jsonToHeaders(parsed.response.headers),

originalRequest: request,
})

services.example.print(response)
const fn = async () => {
try {
const { saveOrNot } = (await Enquirer.prompt({
name: 'saveOrNot',
type: 'select',
message: 'save changes?',
choices: [{ name: 'yes' }, { name: 'no' }],
})) as any

return saveOrNot
} catch (e) {
return 'no'
}
}
const saveOrNot = await fn()

if (saveOrNot == 'yes') {
resource.update(response)
await services.collection.save(cmd, co)
}
}
}
5 changes: 1 addition & 4 deletions src/services/cmdopts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,7 @@ export class CmdOptsService {
const headersString =
cmd.parent.opts().headers || services.env.globalHeaders || '{}'
const headers = JSON.parse(headersString)
const result = Object.entries(headers).map(([k, v]) => {
const value: string | any = v
return new psdk.Header({ key: k, value, system: true })
})
const result = services.common.jsonToHeaders(headers)
return result
}
}
Expand Down
25 changes: 20 additions & 5 deletions src/services/common.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import fs from 'fs-extra'
import psdk from 'postman-collection'
import util, { inspect } from 'node:util'
import lodash from 'lodash'
import newman, { NewmanRunOptions, NewmanRunSummary } from 'newman'
import services from '@src/services/index.js'
import pretty from 'js-object-pretty-print'

export class CommonService {
_ = lodash
Expand Down Expand Up @@ -39,11 +41,16 @@ export class CommonService {
* into JSON-parsable string.
*/
toJsonString(input: string) {
const keyMatcher = '([^",{}\\s]+?)'
const valMatcher = '(.,*)'
const matcher = new RegExp(`${keyMatcher}\\s*:\\s*${valMatcher}`, 'g')
const parser = (_, key, value) => `"${key}":${value}`
return input.replace(matcher, parser)
//const keyMatcher = '([^",{}\\s]+?)'
//const valMatcher = '(.,*)'
//const matcher = new RegExp(`${keyMatcher}\\s*:\\s*${valMatcher}`, 'g')
//const parser = (_, key, value) => `"${key}":${value}`
//return input.replace(matcher, parser)

//return input.replace(/([\$\w]+)\s*:/g, function (_, $1) {return '"' + $1 + '":'})
//.replace(/'([^']+)'/g, function (_, $1) {return '"' + $1 + '"'})

return pretty.pretty(input, 4, 'JSON')
}

isJson(input: string) {
Expand All @@ -55,6 +62,14 @@ export class CommonService {
}
}

jsonToHeaders(jsonHeaders: Record<string, any>) {
const result = Object.entries(jsonHeaders).map(([k, v]) => {
const value: string | any = v
return new psdk.Header({ key: k, value })
})
return result
}

/**
* Pretty-prints an object recursively.
*/
Expand Down
22 changes: 20 additions & 2 deletions src/services/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ import { PostmanCli } from '@src/types.js'
import psdk from 'postman-collection'
import services from '@src/services/index.js'

type ToPrintableOpts = {
addParsedBody?: true
}

/**
* Mostly an abstraction over psdk.Response
* for cmd-show.
*/
export class ExampleService {
toPrintable(r: psdk.Response): PostmanCli.ExamplePrintable {
declare ToPrintableOpts: ToPrintableOpts

toPrintable(
r: psdk.Response,
opts: ToPrintableOpts = {}
): PostmanCli.ExamplePrintable {
let urlMethod = ''
let urlPath = ''
const resultResponse = services.response.toPrintable(r)
Expand All @@ -28,14 +37,23 @@ export class ExampleService {
urlPath = item.request.url.getPath()
}

if (opts.addParsedBody && resultRequest?.$parsedBody) {
resultRequest.body = resultRequest.$parsedBody
delete resultRequest.$parsedBody
}
if (opts.addParsedBody && resultResponse?.$parsedBody) {
resultResponse.body = resultResponse.$parsedBody
delete resultResponse.$parsedBody
}

return { response: resultResponse, request: resultRequest }
}

getPrintString(r: PostmanCli.ExamplePrintable) {
let req = ''
if (r.request) req = services.request.getPrintString(r.request)
const res = services.response.getPrintString(r.response)
return req + '\n\n\n\n' + res
return req + '\n\n' + res
}

print(r: psdk.Response) {
Expand Down
4 changes: 2 additions & 2 deletions src/services/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ export class ResponseService {
},
headers,
body: rawBody,
$parsedBody,
$parseHint,
size: r.size() as any,
time: r.responseTime,
code: r.code,
status: r.status,
$parsedBody,
$parseHint,
}
}

Expand Down

0 comments on commit 2e970e6

Please sign in to comment.