mirror of
https://github.com/curlconverter/curlconverter.git
synced 2022-05-22 02:35:29 +03:00
convert to typescript (#368)
* compile with typescript * add types * rename tree-sitter import file * proofread README.md
This commit is contained in:
committed by
GitHub
parent
9c01335485
commit
f29c397882
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
test/fixtures/
|
||||
24
.eslintrc.json
Normal file
24
.eslintrc.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"no-empty": ["error", { "allowEmptyCatch": true }]
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"out",
|
||||
"dist",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,3 +7,5 @@ npm-debug.log
|
||||
|
||||
# Generated by `npm run prepare`
|
||||
tree-sitter-bash.wasm
|
||||
|
||||
dist/
|
||||
|
||||
11
.npmignore
11
.npmignore
@@ -5,12 +5,11 @@ Standard.xml
|
||||
|
||||
.github/*
|
||||
.gitattributes
|
||||
|
||||
docs/*
|
||||
.gitmodules
|
||||
|
||||
extract_curl_args.py
|
||||
|
||||
fixtures/*
|
||||
tools/*
|
||||
test.js
|
||||
test-utils.js
|
||||
src/tools
|
||||
test
|
||||
dist/test
|
||||
dist/tools
|
||||
|
||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
18
README.md
18
README.md
@@ -84,14 +84,14 @@ Note: you have to add `"type": "module"` to your package.json for the above exam
|
||||
|
||||
Make sure you're running **Node 12** or greater. The test suite will fail on older versions of Node.js.
|
||||
|
||||
If you add a new generator, make sure to update the list of supported languages in [bin/cli.js](bin/cli.js) or else it won't be accessible from the command line. Further, you'll want to update test.js and index.js for your new generator to make it part of the testing.
|
||||
If you add a new generator, make sure to update the list of supported languages in [src/cli.ts](src/cli.ts) or else it won't be accessible from the command line. Further, you'll want to update test.js and index.js for your new generator to make it part of the testing.
|
||||
|
||||
If you want to add new functionality, start with a test.
|
||||
|
||||
- Create a file containing the curl command in `fixtures/curl_commands` with a descriptive filename like `post_with_headers.sh`
|
||||
- Create a file containing the output in `fixtures/python/` with a matching filename (but different extension) like `post_with_headers.py`
|
||||
- Create a file containing the curl command in `test/fixtures/curl_commands` with a descriptive filename like `post_with_headers.sh`
|
||||
- Create a file containing the output in `test/fixtures/python/` with a matching filename (but different extension) like `post_with_headers.py`
|
||||
- Run tests with `npm test`.
|
||||
- If your filenames match correctly, you should see one failing test. Fix it by modifying the parser in `util.js` or the generators in `generators/`
|
||||
- If your filenames match correctly, you should see one failing test. Fix it by modifying the parser in `util.ts` or the generators in `src/generators/`
|
||||
|
||||
The parser generates a generic data structure consumed by code generator functions.
|
||||
|
||||
@@ -99,25 +99,21 @@ You can run a specific test with:
|
||||
|
||||
``` sh
|
||||
npm test -- test_name
|
||||
# or
|
||||
node test.js test_name
|
||||
```
|
||||
|
||||
where `test_name` is a file (without the `.sh` extension) in `fixtures/curl_commands/`
|
||||
where `test_name` is a file (without the `.sh` extension) in `test/fixtures/curl_commands/`
|
||||
|
||||
You can run only the tests for a specific language generator with:
|
||||
|
||||
``` sh
|
||||
npm test -- --language=python
|
||||
# or
|
||||
node test.js --language=python
|
||||
```
|
||||
|
||||
I recommend setting this up with a debugger so you can see exactly what the parser is passing to the generator.
|
||||
Here's my Intellij run configuration for a single test:
|
||||

|
||||
|
||||
Before submitting a PR, please check that your JS code conforms to the code style enforced by [StandardJS](https://standardjs.com) with
|
||||
Before submitting a PR, please check that your JS code conforms to our code style with
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
@@ -126,7 +122,7 @@ npm run lint
|
||||
Use the following to fix your code if it doesn't:
|
||||
|
||||
```sh
|
||||
npm run lint:fix
|
||||
npm run fix
|
||||
```
|
||||
|
||||
If you get stuck, please reach out via email. I am always willing to hop on a Google Hangout and pair program.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
4263
package-lock.json
generated
4263
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
62
package.json
62
package.json
@@ -1,14 +1,17 @@
|
||||
{
|
||||
"name": "curlconverter",
|
||||
"version": "4.0.0-alpha.10",
|
||||
"description": "convert curl commands to Python, JavaScript, Go, PHP and other languages",
|
||||
"homepage": "https://github.com/curlconverter/curlconverter",
|
||||
"description": "convert Curl commands to Python, JavaScript, Go, PHP and other languages",
|
||||
"homepage": "https://curlconverter.com",
|
||||
"author": {
|
||||
"name": "Nick Carneiro",
|
||||
"email": "nickc@trillworks.com",
|
||||
"url": "http://trillworks.com"
|
||||
"url": "https://trillworks.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/curlconverter/curlconverter.git"
|
||||
},
|
||||
"repository": "curlconverter/curlconverter",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"curl",
|
||||
@@ -17,11 +20,10 @@
|
||||
"python",
|
||||
"converter"
|
||||
],
|
||||
"main": "dist/src/index.js",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@curlconverter/tree-sitter-bash": "^0.0.2",
|
||||
"cookie": "^0.4.2",
|
||||
"jsesc": "^3.0.2",
|
||||
"nunjucks": "^3.2.3",
|
||||
"query-string": "^7.1.1",
|
||||
@@ -30,30 +32,44 @@
|
||||
"yamljs": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/diff": "^5.0.2",
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/jsesc": "^3.0.1",
|
||||
"@types/nunjucks": "^3.2.1",
|
||||
"@types/tape": "^4.13.2",
|
||||
"@types/yamljs": "^0.2.31",
|
||||
"@types/yargs": "^17.0.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.17.0",
|
||||
"@typescript-eslint/parser": "^5.17.0",
|
||||
"colors": "^1.4.0",
|
||||
"diff": "^5.0.0",
|
||||
"standard": "^17.0.0-2",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"glob": "^7.2.0",
|
||||
"mocha": "^9.2.2",
|
||||
"prettier": "^2.6.1",
|
||||
"tape": "^5.5.2",
|
||||
"tree-sitter-cli": "^0.20.6",
|
||||
"yargs": "^17.3.1"
|
||||
"typescript": "^4.6.3",
|
||||
"yargs": "^17.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test.js",
|
||||
"lint": "standard",
|
||||
"lint:fix": "standard --fix",
|
||||
"prepare": "tree-sitter build-wasm --docker node_modules/@curlconverter/tree-sitter-bash",
|
||||
"gen-test": "./tools/gen-test.js",
|
||||
"compare-requests": "./tools/compare-requests.js",
|
||||
"compare-request": "./tools/compare-requests.js"
|
||||
"compile": "tsc",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"pretest": "npm run compile",
|
||||
"test": "NODE_OPTIONS=--enable-source-maps npx tape dist/test/test.js",
|
||||
"prelint": "npm run compile",
|
||||
"lint": "eslint src --ext ts",
|
||||
"prefix": "npm run compile",
|
||||
"fix": "eslint src --ext ts --fix",
|
||||
"prepare": "npm run compile && tree-sitter build-wasm --docker node_modules/@curlconverter/tree-sitter-bash && mv tree-sitter-bash.wasm dist/",
|
||||
"pregen-test": "npm run compile",
|
||||
"gen-test": "node --enable-source-maps ./dist/tools/gen-test.js",
|
||||
"compare-requests": "npm run compile && node --enable-source-maps ./dist/tools/compare-requests.js",
|
||||
"compare-request": "npm run compile && node --enable-source-maps ./dist/tools/compare-requests.js"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"/fixtures/",
|
||||
"/dist/"
|
||||
]
|
||||
},
|
||||
"bin": "bin/cli.js",
|
||||
"bin": "dist/src/cli.js",
|
||||
"browser": {
|
||||
"./parser.js": "./browser-parser.js"
|
||||
"./dist/src/bash-parser.js": "./dist/src/bash-parser-web.js"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { curlLongOpts, curlShortOpts, parseArgs, buildRequest, parseCurlCommand, CCError } from '../util.js'
|
||||
import { curlLongOpts, curlShortOpts, parseArgs, buildRequest, parseCurlCommand, CCError, has } from './util.js'
|
||||
import type { LongOpts, ShortOpts, Request } from './util.js'
|
||||
|
||||
import { _toAnsible } from '../generators/ansible.js'
|
||||
import { _toDart } from '../generators/dart.js'
|
||||
import { _toElixir } from '../generators/elixir.js'
|
||||
import { _toGo } from '../generators/go.js'
|
||||
import { _toJava } from '../generators/java.js'
|
||||
import { _toJavaScript } from '../generators/javascript/javascript.js'
|
||||
import { _toJsonString } from '../generators/json.js'
|
||||
import { _toMATLAB } from '../generators/matlab/matlab.js'
|
||||
import { _toNode } from '../generators/javascript/node-fetch.js'
|
||||
import { _toNodeRequest } from '../generators/javascript/node-request.js'
|
||||
import { _toPhp } from '../generators/php/php.js'
|
||||
import { _toPhpRequests } from '../generators/php/php-requests.js'
|
||||
import { _toPython } from '../generators/python.js'
|
||||
import { _toR } from '../generators/r.js'
|
||||
import { _toRust } from '../generators/rust.js'
|
||||
import { _toStrest } from '../generators/strest.js'
|
||||
import { _toAnsible } from './generators/ansible.js'
|
||||
import { _toDart } from './generators/dart.js'
|
||||
import { _toElixir } from './generators/elixir.js'
|
||||
import { _toGo } from './generators/go.js'
|
||||
import { _toJava } from './generators/java.js'
|
||||
import { _toJavaScript } from './generators/javascript/javascript.js'
|
||||
import { _toJsonString } from './generators/json.js'
|
||||
import { _toMATLAB } from './generators/matlab/matlab.js'
|
||||
import { _toNode } from './generators/javascript/node-fetch.js'
|
||||
import { _toNodeRequest } from './generators/javascript/node-request.js'
|
||||
import { _toPhp } from './generators/php/php.js'
|
||||
import { _toPhpRequests } from './generators/php/php-requests.js'
|
||||
import { _toPython } from './generators/python.js'
|
||||
import { _toR } from './generators/r.js'
|
||||
import { _toRust } from './generators/rust.js'
|
||||
import { _toStrest } from './generators/strest.js'
|
||||
|
||||
import fs from 'fs'
|
||||
|
||||
@@ -29,9 +30,9 @@ const defaultLanguage = 'python'
|
||||
|
||||
// Maps options for --language to functions
|
||||
// NOTE: make sure to update this when adding language support
|
||||
const translate = {
|
||||
const translate: {[key: string]: (request: Request) => string} = {
|
||||
ansible: _toAnsible,
|
||||
browser: _toJavaScript, // backwards compatibility, undocumented
|
||||
browser: _toJavaScript, // for backwards compatibility, undocumented
|
||||
dart: _toDart,
|
||||
elixir: _toElixir,
|
||||
go: _toGo,
|
||||
@@ -74,29 +75,29 @@ language: the language to convert the curl command to. The choices are
|
||||
curl_options: these should be passed exactly as they would be passed to curl.
|
||||
see 'curl --help' or 'curl --manual' for which options are allowed here`
|
||||
|
||||
const curlConverterLongOpts = {
|
||||
const curlConverterLongOpts: LongOpts = {
|
||||
language: { type: 'string', name: 'language' },
|
||||
stdin: { type: 'boolean', name: 'stdin' }
|
||||
stdin: { type: 'bool', name: 'stdin' }
|
||||
}
|
||||
const curlConverterShortOpts = {
|
||||
const curlConverterShortOpts: ShortOpts = {
|
||||
// a single - (dash) tells curlconverter to read input from stdin
|
||||
'': 'stdin'
|
||||
}
|
||||
const opts = [
|
||||
const opts: [LongOpts, ShortOpts] = [
|
||||
{ ...curlLongOpts, ...curlConverterLongOpts },
|
||||
{ ...curlShortOpts, ...curlConverterShortOpts }
|
||||
]
|
||||
|
||||
const exitWithError = (error, verbose = false) => {
|
||||
let errMsg = error
|
||||
function exitWithError (error: unknown, verbose = false): never {
|
||||
let errMsg: Error | string | unknown = error
|
||||
if (!verbose) {
|
||||
if (error instanceof CCError) {
|
||||
errMsg = ''
|
||||
for (const line of error.message.toString().split('\n')) {
|
||||
errMsg += 'error: ' + line + '\n'
|
||||
}
|
||||
errMsg = errMsg.trimEnd()
|
||||
} else {
|
||||
errMsg = (errMsg as string).trimEnd()
|
||||
} else if (error instanceof Error) {
|
||||
// .toString() removes the traceback
|
||||
errMsg = error.toString()
|
||||
}
|
||||
@@ -124,7 +125,7 @@ if (parsedArguments.version) {
|
||||
const argc = Object.keys(parsedArguments).length
|
||||
const language = parsedArguments.language || defaultLanguage
|
||||
const stdin = parsedArguments.stdin
|
||||
if (!Object.prototype.hasOwnProperty.call(translate, language)) {
|
||||
if (!has(translate, language)) {
|
||||
exitWithError(
|
||||
new CCError('unexpected --language: ' + JSON.stringify(language) + '\n' +
|
||||
'must be one of: ' + Object.keys(translate).join(', ')),
|
||||
@@ -168,7 +169,7 @@ if (argc === 0) {
|
||||
}
|
||||
|
||||
// Warning for users using the pre-4.0 CLI
|
||||
if (request.url && request.url.startsWith('curl ')) {
|
||||
if (request.url?.startsWith('curl ')) {
|
||||
console.error('warning: Passing a whole curl command as a single argument?')
|
||||
console.error('warning: Pass options to curlconverter as if it was curl instead:')
|
||||
console.error("warning: curlconverter 'curl example.com' -> curlconverter example.com")
|
||||
@@ -1,8 +1,11 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request} from '../util.js'
|
||||
import { ansibleTemplate } from '../templates/ansible.js'
|
||||
|
||||
import nunjucks from 'nunjucks'
|
||||
import querystring from 'query-string'
|
||||
import { ansibleTemplate } from '../templates/ansible.js'
|
||||
function getDataString (request) {
|
||||
|
||||
function getDataString (request: Request): any {
|
||||
const parsedQueryString = querystring.parse(request.data, { sort: false })
|
||||
const keyCount = Object.keys(parsedQueryString).length
|
||||
const singleKeyOnly = keyCount === 1 && !parsedQueryString[Object.keys(parsedQueryString)[0]]
|
||||
@@ -16,7 +19,7 @@ function getDataString (request) {
|
||||
return request.data
|
||||
}
|
||||
|
||||
export const _toAnsible = request => {
|
||||
export const _toAnsible = (request: Request): string => {
|
||||
let convertedData
|
||||
if (request.data && typeof request.data === 'string') {
|
||||
convertedData = getDataString(request)
|
||||
@@ -24,7 +27,7 @@ export const _toAnsible = request => {
|
||||
const result = nunjucks.renderString(ansibleTemplate, { request, data: convertedData })
|
||||
return result
|
||||
}
|
||||
export const toAnsible = curlCommand => {
|
||||
export const toAnsible = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toAnsible(request)
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request} from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
function repr (value) {
|
||||
function repr (value: string): string {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
if (!value) {
|
||||
return "''"
|
||||
@@ -10,7 +12,7 @@ function repr (value) {
|
||||
}
|
||||
}
|
||||
|
||||
export const _toDart = r => {
|
||||
export const _toDart = (r: Request): string => {
|
||||
let s = ''
|
||||
|
||||
if (r.auth || r.isDataBinary) s += "import 'dart:convert';\n"
|
||||
@@ -47,8 +49,7 @@ export const _toDart = r => {
|
||||
s += '\n'
|
||||
}
|
||||
|
||||
const hasQuery = r.query
|
||||
if (hasQuery) {
|
||||
if (r.query) {
|
||||
// TODO: dict won't work with repeated keys
|
||||
s += ' var params = {\n'
|
||||
for (const [paramName, rawValue] of r.query) {
|
||||
@@ -84,7 +85,7 @@ export const _toDart = r => {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasQuery) {
|
||||
if (r.query) {
|
||||
s += " var url = Uri.parse('" + r.urlWithoutQuery + "?$query');\n"
|
||||
} else {
|
||||
s += " var url = Uri.parse('" + r.url + "');\n"
|
||||
@@ -104,7 +105,7 @@ export const _toDart = r => {
|
||||
|
||||
return s + '\n'
|
||||
}
|
||||
export const toDart = curlCommand => {
|
||||
export const toDart = (curlCommand: string | string[]): string => {
|
||||
const r = util.parseCurlCommand(curlCommand)
|
||||
return _toDart(r)
|
||||
}
|
||||
@@ -1,18 +1,21 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request} from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
import querystring from 'query-string'
|
||||
|
||||
function repr (value) {
|
||||
// TODO: I bet elixir's array syntax is different and if the query string
|
||||
// values are arrays that actually generates broken code.
|
||||
function repr (value: string | null | (string | null)[]): string {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
if (!value) {
|
||||
return '""'
|
||||
} else {
|
||||
return `~s|${jsesc(value, { quotes: 'backticks' })}|`
|
||||
return `~s|${jsesc(value, { quotes: 'backtick' })}|`
|
||||
}
|
||||
}
|
||||
|
||||
function getCookies (request) {
|
||||
function getCookies (request: Request): string {
|
||||
if (!request.cookies) {
|
||||
return ''
|
||||
}
|
||||
@@ -24,7 +27,7 @@ function getCookies (request) {
|
||||
return `cookies: [~s|${cookies.join('; ')}|]`
|
||||
}
|
||||
|
||||
function getOptions (request) {
|
||||
function getOptions (request: Request): string {
|
||||
const hackneyOptions = []
|
||||
|
||||
const auth = getBasicAuth(request)
|
||||
@@ -49,7 +52,7 @@ function getOptions (request) {
|
||||
return `[${hackneyOptionsString}]`
|
||||
}
|
||||
|
||||
function getBasicAuth (request) {
|
||||
function getBasicAuth (request: Request): string {
|
||||
if (!request.auth) {
|
||||
return ''
|
||||
}
|
||||
@@ -58,7 +61,7 @@ function getBasicAuth (request) {
|
||||
return `basic_auth: {${repr(user)}, ${repr(password)}}`
|
||||
}
|
||||
|
||||
function getQueryDict (request) {
|
||||
function getQueryDict (request: Request): string {
|
||||
if (!request.query) {
|
||||
return '[]'
|
||||
}
|
||||
@@ -70,7 +73,7 @@ function getQueryDict (request) {
|
||||
return queryDict
|
||||
}
|
||||
|
||||
function getHeadersDict (request) {
|
||||
function getHeadersDict (request: Request): string {
|
||||
if (!request.headers) {
|
||||
return '[]'
|
||||
}
|
||||
@@ -82,7 +85,7 @@ function getHeadersDict (request) {
|
||||
return dict
|
||||
}
|
||||
|
||||
function getBody (request) {
|
||||
function getBody (request: Request): string {
|
||||
const formData = getFormDataString(request)
|
||||
|
||||
if (formData) {
|
||||
@@ -92,7 +95,7 @@ function getBody (request) {
|
||||
return '""'
|
||||
}
|
||||
|
||||
function getFormDataString (request) {
|
||||
function getFormDataString (request: Request): string {
|
||||
if (request.data && typeof request.data === 'string') {
|
||||
return getDataString(request)
|
||||
}
|
||||
@@ -101,8 +104,8 @@ function getFormDataString (request) {
|
||||
return ''
|
||||
}
|
||||
|
||||
let fileArgs = []
|
||||
let dataArgs = []
|
||||
let fileArgs: string[] | string = []
|
||||
let dataArgs: string[] | string = []
|
||||
for (const [multipartKey, multipartValue] of request.multipartUploads) {
|
||||
if (multipartValue.startsWith('@')) {
|
||||
const fileName = multipartValue.slice(1)
|
||||
@@ -112,7 +115,7 @@ function getFormDataString (request) {
|
||||
}
|
||||
}
|
||||
|
||||
let content = []
|
||||
let content: string[] | string = []
|
||||
fileArgs = fileArgs.join(',\n')
|
||||
if (fileArgs) {
|
||||
content.push(fileArgs)
|
||||
@@ -133,7 +136,7 @@ ${content}
|
||||
return ''
|
||||
}
|
||||
|
||||
function getDataString (request) {
|
||||
function getDataString (request: Request): string {
|
||||
if (!request.isDataRaw && request.data.startsWith('@')) {
|
||||
const filePath = request.data.slice(1)
|
||||
if (request.isDataBinary) {
|
||||
@@ -155,7 +158,7 @@ function getDataString (request) {
|
||||
}
|
||||
}
|
||||
|
||||
function getMultipleDataString (request, parsedQueryString) {
|
||||
function getMultipleDataString (request: Request, parsedQueryString: querystring.ParsedQuery<string>): string {
|
||||
let repeatedKey = false
|
||||
for (const key in parsedQueryString) {
|
||||
const value = parsedQueryString[key]
|
||||
@@ -194,7 +197,7 @@ ${data.join(',\n')}
|
||||
return dataString
|
||||
}
|
||||
|
||||
export const _toElixir = request => {
|
||||
export const _toElixir = (request: Request): string => {
|
||||
// curl automatically prepends 'http' if the scheme is missing, but python fails and returns an error
|
||||
// we tack it on here to mimic curl
|
||||
if (!request.url.match(/https?:/)) {
|
||||
@@ -221,7 +224,7 @@ response = HTTPoison.request(request)
|
||||
|
||||
return template
|
||||
}
|
||||
export const toElixir = curlCommand => {
|
||||
export const toElixir = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toElixir(request)
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request} from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
export const _toGo = request => {
|
||||
export const _toGo = (request: Request): string => {
|
||||
let goCode = 'package main\n\n'
|
||||
goCode += 'import (\n\t"fmt"\n\t"io/ioutil"\n\t"log"\n\t"net/http"\n)\n\n'
|
||||
goCode += 'func main() {\n'
|
||||
@@ -42,7 +44,7 @@ export const _toGo = request => {
|
||||
|
||||
return goCode + '\n'
|
||||
}
|
||||
export const toGo = curlCommand => {
|
||||
export const toGo = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toGo(request)
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request} from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
const doubleQuotes = str => jsesc(str, { quotes: 'double' })
|
||||
const doubleQuotes = (str: string): string => jsesc(str, { quotes: 'double' })
|
||||
|
||||
export const _toJava = request => {
|
||||
export const _toJava = (request: Request): string => {
|
||||
let javaCode = ''
|
||||
|
||||
if (request.auth) {
|
||||
@@ -31,8 +32,11 @@ export const _toJava = request => {
|
||||
let gzip = false
|
||||
if (request.headers) {
|
||||
for (const [headerName, headerValue] of request.headers) {
|
||||
if (headerValue === null) {
|
||||
continue
|
||||
}
|
||||
javaCode += '\t\thttpConn.setRequestProperty("' + headerName + '", "' + doubleQuotes(headerValue) + '");\n'
|
||||
if (headerName.toLowerCase() === 'accept-encoding') {
|
||||
if (headerName.toLowerCase() === 'accept-encoding' && headerValue) {
|
||||
gzip = headerValue.indexOf('gzip') !== -1
|
||||
}
|
||||
}
|
||||
@@ -74,7 +78,7 @@ export const _toJava = request => {
|
||||
|
||||
return javaCode + '\n'
|
||||
}
|
||||
export const toJava = curlCommand => {
|
||||
export const toJava = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toJava(request)
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as util from '../../util.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
export const _toJavaScript = request => {
|
||||
export const _toJavaScript = (request: Request): string => {
|
||||
let jsFetchCode = ''
|
||||
|
||||
if (request.data) {
|
||||
@@ -73,7 +75,7 @@ export const _toJavaScript = request => {
|
||||
return jsFetchCode + '\n'
|
||||
}
|
||||
|
||||
export const toJavaScript = curlCommand => {
|
||||
export const toJavaScript = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toJavaScript(request)
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import * as util from '../../util.js'
|
||||
import type { Request } from '../../util.js'
|
||||
import { _toJavaScript } from './javascript.js'
|
||||
|
||||
const importStatement = 'var fetch = require(\'node-fetch\');\n\n'
|
||||
|
||||
export const _toNode = request => {
|
||||
export const _toNode = (request: Request): string => {
|
||||
return importStatement + _toJavaScript(request)
|
||||
}
|
||||
export const toNode = curlCommand => {
|
||||
export const toNode = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toNode(request)
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as util from '../../util.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
export const _toNodeRequest = request => {
|
||||
export const _toNodeRequest = (request: Request): string => {
|
||||
let nodeRequestCode = 'var request = require(\'request\');\n\n'
|
||||
if (request.headers) {
|
||||
nodeRequestCode += 'var headers = {\n'
|
||||
@@ -62,7 +64,7 @@ export const _toNodeRequest = request => {
|
||||
|
||||
return nodeRequestCode + '\n'
|
||||
}
|
||||
export const toNodeRequest = curlCommand => {
|
||||
export const toNodeRequest = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toNodeRequest(request)
|
||||
}
|
||||
@@ -1,22 +1,26 @@
|
||||
// Author: ssi-anik (sirajul.islam.anik@gmail.com)
|
||||
|
||||
import * as util from '../util.js'
|
||||
import type { Request, QueryDict } from '../util.js'
|
||||
|
||||
import querystring from 'query-string'
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
function repr (value, isKey) {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
/*
|
||||
if ( !value ) {
|
||||
return ""
|
||||
} else {
|
||||
return "'" + jsesc(value, { quotes: 'single' }) + "'"
|
||||
} */
|
||||
return isKey ? "'" + jsesc(value, { quotes: 'single' }) + "'" : value
|
||||
type JSONOutput = {
|
||||
url: string,
|
||||
raw_url: string,
|
||||
method: string,
|
||||
cookies?: { [key: string]: string },
|
||||
headers?: { [key: string]: string | null },
|
||||
queries?: QueryDict,
|
||||
data?: { [key: string]: string },
|
||||
// raw_data?: string[],
|
||||
files?: { [key: string]: string },
|
||||
// raw_files: string[],
|
||||
insecure?: boolean,
|
||||
auth?: {user: string, password: string},
|
||||
}
|
||||
|
||||
function getDataString (request) {
|
||||
function getDataString (request: Request) {
|
||||
/*
|
||||
if ( !request.isDataRaw && request.data.startsWith('@') ) {
|
||||
var filePath = request.data.slice(1);
|
||||
@@ -29,57 +33,55 @@ function getDataString (request) {
|
||||
const singleKeyOnly = keyCount === 1 && !parsedQueryString[Object.keys(parsedQueryString)[0]]
|
||||
const singularData = request.isDataBinary || singleKeyOnly
|
||||
if (singularData) {
|
||||
const data = {}
|
||||
const data: {[key: string]: string} = {}
|
||||
// TODO: dataRaw = request.data ?
|
||||
data[repr(request.data)] = ''
|
||||
data[request.data] = ''
|
||||
return { data }
|
||||
} else {
|
||||
return getMultipleDataString(request, parsedQueryString)
|
||||
}
|
||||
}
|
||||
|
||||
function getMultipleDataString (request, parsedQueryString) {
|
||||
const data = {}
|
||||
function getMultipleDataString (request: Request, parsedQueryString: querystring.ParsedQuery<string> ) {
|
||||
const data: {[key: string]: string | string[]} = {}
|
||||
|
||||
for (const key in parsedQueryString) {
|
||||
const value = parsedQueryString[key]
|
||||
if (Array.isArray(value)) {
|
||||
data[repr(key)] = value
|
||||
data[key] = value.map((v: string | null) => v ? v : '')
|
||||
} else {
|
||||
data[repr(key)] = repr(value)
|
||||
data[key] = value ? value : ''
|
||||
}
|
||||
}
|
||||
|
||||
return { data }
|
||||
}
|
||||
|
||||
function getFilesString (request) {
|
||||
const data = {}
|
||||
|
||||
data.files = {}
|
||||
data.data = {}
|
||||
function getFilesString (request: Request): {'files'?: {[key: string]: string}, 'data'?: {[key: string]: string}} | undefined {
|
||||
if (!request.multipartUploads) {
|
||||
return undefined
|
||||
}
|
||||
const data: {files: { [key: string]: string }, data: { [key: string]: string }} = {
|
||||
files : {},
|
||||
data : {}
|
||||
}
|
||||
|
||||
for (const [multipartKey, multipartValue] of request.multipartUploads) {
|
||||
if (multipartValue.startsWith('@')) {
|
||||
const fileName = multipartValue.slice(1)
|
||||
data.files[repr(multipartKey)] = repr(fileName)
|
||||
data.files[multipartKey] = fileName
|
||||
} else {
|
||||
data.data[repr(multipartKey)] = repr(multipartValue)
|
||||
data.data[multipartKey] = multipartValue
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(data.files).length === 0) {
|
||||
delete data.files
|
||||
return {
|
||||
files: Object.keys(data.files).length ? data.files : undefined,
|
||||
data: Object.keys(data.data).length ? data.data : undefined
|
||||
}
|
||||
|
||||
if (Object.keys(data.data).length === 0) {
|
||||
delete data.data
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
export const _toJsonString = request => {
|
||||
export const _toJsonString = (request: Request) => {
|
||||
// curl automatically prepends 'http' if the scheme is missing, but python fails and returns an error
|
||||
// we tack it on here to mimic curl
|
||||
if (!request.url.match(/https?:/)) {
|
||||
@@ -89,7 +91,7 @@ export const _toJsonString = request => {
|
||||
request.urlWithoutQuery = 'http://' + request.urlWithoutQuery
|
||||
}
|
||||
|
||||
const requestJson = {
|
||||
const requestJson: JSONOutput = {
|
||||
url: (request.queryDict ? request.urlWithoutQuery : request.url).replace(/\/$/, ''),
|
||||
// url: request.queryDict ? request.urlWithoutQuery : request.url,
|
||||
raw_url: request.url,
|
||||
@@ -118,6 +120,7 @@ export const _toJsonString = request => {
|
||||
requestJson.queries = request.queryDict
|
||||
}
|
||||
|
||||
// TODO: not Object.assign, doesn't work with type system
|
||||
if (request.data && typeof request.data === 'string') {
|
||||
Object.assign(requestJson, getDataString(request))
|
||||
} else if (request.multipartUploads) {
|
||||
@@ -131,14 +134,14 @@ export const _toJsonString = request => {
|
||||
if (request.auth) {
|
||||
const [user, password] = request.auth
|
||||
requestJson.auth = {
|
||||
user: repr(user),
|
||||
password: repr(password)
|
||||
user: user,
|
||||
password: password
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(Object.keys(requestJson).length ? requestJson : '{}', null, 4) + '\n'
|
||||
}
|
||||
export const toJsonString = curlCommand => {
|
||||
export const toJsonString = (curlCommand: string | string[]) => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toJsonString(request)
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { CCError } from '../../util.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
const repr = (value) => {
|
||||
const repr = (value?: string | null) => {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
if (!value) {
|
||||
return "''"
|
||||
@@ -11,7 +12,7 @@ const repr = (value) => {
|
||||
return "'" + jsesc(value, { quotes: 'single' }).replace(/\\'/g, "''") + "'"
|
||||
}
|
||||
|
||||
const setVariableValue = (outputVariable, value, termination) => {
|
||||
const setVariableValue = (outputVariable: string | null, value: string, termination?: string): string => {
|
||||
let result = ''
|
||||
|
||||
if (outputVariable) {
|
||||
@@ -23,7 +24,7 @@ const setVariableValue = (outputVariable, value, termination) => {
|
||||
return result
|
||||
}
|
||||
|
||||
const callFunction = (outputVariable, functionName, params, termination) => {
|
||||
const callFunction = (outputVariable: string | null, functionName: string, params: string | string[] | string[][], termination?: string) => {
|
||||
let functionCall = functionName + '('
|
||||
if (Array.isArray(params)) {
|
||||
const singleLine = params.map(x => Array.isArray(x) ? x.join(', ') : x).join(', ')
|
||||
@@ -47,7 +48,7 @@ const callFunction = (outputVariable, functionName, params, termination) => {
|
||||
return setVariableValue(outputVariable, functionCall, termination)
|
||||
}
|
||||
|
||||
const addCellArray = (mapping, keysNotToQuote, keyValSeparator, indentLevel, pairs) => {
|
||||
const addCellArray = (mapping: {[key: string]: string | null | (null | string)[]}, keysNotToQuote: string[], keyValSeparator: string, indentLevel: number, pairs?: boolean) => {
|
||||
const indentUnit = ' '.repeat(4)
|
||||
const indent = indentUnit.repeat(indentLevel)
|
||||
const indentPrevLevel = indentUnit.repeat(indentLevel - 1)
|
||||
@@ -57,22 +58,27 @@ const addCellArray = (mapping, keysNotToQuote, keyValSeparator, indentLevel, pai
|
||||
|
||||
let response = pairs ? '' : '{'
|
||||
if (entries.length === 1) {
|
||||
let [key, value] = entries.pop()
|
||||
if (keysNotToQuote && !keysNotToQuote.includes(key)) value = `${repr(value)}`
|
||||
response += `${repr(key)}${keyValSeparator} ${value}`
|
||||
const [key, value] = entries.pop() as [string, string]
|
||||
let val = value
|
||||
if (keysNotToQuote && !keysNotToQuote.includes(key)) val = `${repr(value)}`
|
||||
response += `${repr(key)}${keyValSeparator} ${val}`
|
||||
} else {
|
||||
if (pairs) response += '...'
|
||||
let counter = entries.length
|
||||
for (let [key, value] of entries) {
|
||||
for (const [key, value] of entries) {
|
||||
let val = value
|
||||
if (val === null) {
|
||||
continue
|
||||
}
|
||||
--counter
|
||||
if (keysNotToQuote && !keysNotToQuote.includes(key)) {
|
||||
if (typeof value === 'object') {
|
||||
value = `[${value.map(repr).join()}]`
|
||||
if (typeof val === 'object') {
|
||||
val = `[${val.map(repr).join()}]`
|
||||
} else {
|
||||
value = `${repr(value)}`
|
||||
val = `${repr(val)}`
|
||||
}
|
||||
}
|
||||
response += `\n${indent}${repr(key)}${keyValSeparator} ${value}`
|
||||
response += `\n${indent}${repr(key)}${keyValSeparator} ${val}`
|
||||
if (pairs) {
|
||||
if (counter !== 0) response += ','
|
||||
response += '...'
|
||||
@@ -84,7 +90,7 @@ const addCellArray = (mapping, keysNotToQuote, keyValSeparator, indentLevel, pai
|
||||
return response
|
||||
}
|
||||
|
||||
const structify = (obj, indentLevel) => {
|
||||
const structify = (obj: any, indentLevel?: number) => {
|
||||
let response = ''
|
||||
indentLevel = !indentLevel ? 1 : ++indentLevel
|
||||
const indent = ' '.repeat(4 * indentLevel)
|
||||
@@ -137,27 +143,25 @@ const structify = (obj, indentLevel) => {
|
||||
return response
|
||||
}
|
||||
|
||||
const containsBody = (request) => {
|
||||
return Object.prototype.hasOwnProperty.call(request, 'data') || request.multipartUploads
|
||||
const containsBody = (request: Request): boolean => {
|
||||
return Boolean(Object.prototype.hasOwnProperty.call(request, 'data') || request.multipartUploads)
|
||||
}
|
||||
|
||||
const prepareQueryString = (request) => {
|
||||
let response = null
|
||||
const prepareQueryString = (request: Request): string | null => {
|
||||
if (request.queryDict) {
|
||||
const params = addCellArray(request.queryDict, [], '', 1)
|
||||
response = setVariableValue('params', params)
|
||||
return setVariableValue('params', params)
|
||||
}
|
||||
return response
|
||||
return null
|
||||
}
|
||||
|
||||
const prepareCookies = (request) => {
|
||||
let response = null
|
||||
const prepareCookies = (request: Request): string | null => {
|
||||
if (request.cookies) {
|
||||
// TODO: throws away repeat cookies
|
||||
const cookies = addCellArray(Object.fromEntries(request.cookies), [], '', 1)
|
||||
response = setVariableValue('cookies', cookies)
|
||||
return setVariableValue('cookies', cookies)
|
||||
}
|
||||
return response
|
||||
return null
|
||||
}
|
||||
|
||||
const cookieString = 'char(join(join(cookies, \'=\'), \'; \'))'
|
||||
@@ -3,8 +3,9 @@ import {
|
||||
structify, containsBody, prepareQueryString,
|
||||
prepareCookies
|
||||
} from './common.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
const prepareHeaders = (request) => {
|
||||
const prepareHeaders = (request: Request): string | null => {
|
||||
let response = null
|
||||
|
||||
if (request.headers) {
|
||||
@@ -15,6 +16,9 @@ const prepareHeaders = (request) => {
|
||||
let header = headerCount === 1 ? '' : '['
|
||||
|
||||
for (const [key, value] of request.headers) {
|
||||
if (value === null) {
|
||||
continue
|
||||
}
|
||||
switch (key) {
|
||||
case 'Cookie':
|
||||
break
|
||||
@@ -55,7 +59,7 @@ const prepareHeaders = (request) => {
|
||||
return response
|
||||
}
|
||||
|
||||
const prepareURI = (request) => {
|
||||
const prepareURI = (request: Request) => {
|
||||
const uriParams = []
|
||||
if (request.queryDict) {
|
||||
uriParams.push(repr(request.urlWithoutQuery))
|
||||
@@ -66,7 +70,7 @@ const prepareURI = (request) => {
|
||||
return callFunction('uri', 'URI', uriParams)
|
||||
}
|
||||
|
||||
const prepareAuth = (request) => {
|
||||
const prepareAuth = (request: Request): string[] => {
|
||||
const options = []
|
||||
const optionsParams = []
|
||||
if (request.auth) {
|
||||
@@ -89,16 +93,13 @@ const prepareAuth = (request) => {
|
||||
return options
|
||||
}
|
||||
|
||||
const prepareMultipartUploads = (request) => {
|
||||
const prepareMultipartUploads = (request: Request): string | null => {
|
||||
let response = null
|
||||
if (request.multipartUploads) {
|
||||
const params = []
|
||||
const params: [string, string][] = []
|
||||
for (const [key, value] of request.multipartUploads) {
|
||||
const pair = []
|
||||
pair.push(repr(key))
|
||||
const fileProvider = prepareDataProvider(value, null, '', 1)
|
||||
pair.push(fileProvider)
|
||||
params.push(pair)
|
||||
params.push([repr(key), fileProvider as string]) // TODO: can this be not a string?
|
||||
}
|
||||
response = callFunction('body', 'MultipartFormProvider', params)
|
||||
}
|
||||
@@ -106,7 +107,7 @@ const prepareMultipartUploads = (request) => {
|
||||
return response
|
||||
}
|
||||
|
||||
const isJsonString = (str) => {
|
||||
const isJsonString = (str: string): boolean => {
|
||||
// Source: https://stackoverflow.com/a/3710226/5625738
|
||||
try {
|
||||
JSON.parse(str)
|
||||
@@ -116,7 +117,7 @@ const isJsonString = (str) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const prepareDataProvider = (value, output, termination, indentLevel, isDataBinary, isDataRaw) => {
|
||||
const prepareDataProvider = (value: string, output: string | null, termination: string, indentLevel: number, isDataBinary?: boolean, isDataRaw?: boolean): string | string[] => {
|
||||
if (typeof indentLevel === 'undefined' || indentLevel === null) indentLevel = 0
|
||||
if (typeof isDataBinary === 'undefined') isDataBinary = true
|
||||
if (!isDataRaw && value[0] === '@') {
|
||||
@@ -155,10 +156,10 @@ const prepareDataProvider = (value, output, termination, indentLevel, isDataBina
|
||||
return callFunction(output, 'FormProvider', formValue, termination)
|
||||
}
|
||||
|
||||
const prepareData = (request) => {
|
||||
const prepareData = (request: Request) => {
|
||||
let response = null
|
||||
if (request.dataArray) {
|
||||
const data = request.dataArray.map(x => x.split('=').map(x => {
|
||||
const data = request.dataArray.map((x: string) => x.split('=').map(x => {
|
||||
let ans = repr(x)
|
||||
try {
|
||||
const jsonData = JSON.parse(x)
|
||||
@@ -180,8 +181,8 @@ const prepareData = (request) => {
|
||||
return response
|
||||
}
|
||||
|
||||
const prepareRequestMessage = (request) => {
|
||||
let reqMessage = [repr(request.method.toLowerCase())]
|
||||
const prepareRequestMessage = (request: Request): string => {
|
||||
let reqMessage: string[] | string = [repr(request.method.toLowerCase())]
|
||||
if (request.cookie || request.headers) {
|
||||
reqMessage.push('header')
|
||||
} else if (request.method.toLowerCase() === 'get') {
|
||||
@@ -189,9 +190,10 @@ const prepareRequestMessage = (request) => {
|
||||
}
|
||||
if (containsBody(request)) {
|
||||
if (reqMessage.length === 1) {
|
||||
reqMessage.push('[]')
|
||||
// TODO: this could be a string actually
|
||||
(reqMessage as string[]).push('[]')
|
||||
}
|
||||
reqMessage.push('body')
|
||||
(reqMessage as string[]).push('body')
|
||||
}
|
||||
|
||||
// list as many params as necessary
|
||||
@@ -207,7 +209,7 @@ const prepareRequestMessage = (request) => {
|
||||
return response.join('\n')
|
||||
}
|
||||
|
||||
export const toHTTPInterface = (request) => {
|
||||
export const toHTTPInterface = (request: Request): (string | string[] | null)[] => {
|
||||
return [
|
||||
'%% HTTP Interface',
|
||||
'import matlab.net.*',
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as util from '../../util.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
import { toWebServices } from './webservices.js'
|
||||
import { toHTTPInterface } from './httpinterface.js'
|
||||
|
||||
export const _toMATLAB = request => {
|
||||
export const _toMATLAB = (request: Request): string => {
|
||||
const lines = toWebServices(request).concat('', toHTTPInterface(request))
|
||||
return lines.flat().filter(line => line !== null).join('\n')
|
||||
}
|
||||
export const toMATLAB = curlCommand => {
|
||||
export const toMATLAB = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toMATLAB(request)
|
||||
}
|
||||
@@ -4,16 +4,17 @@ import {
|
||||
prepareQueryString, prepareCookies,
|
||||
cookieString, paramsString
|
||||
} from './common.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
const isSupportedByWebServices = (request) => {
|
||||
const isSupportedByWebServices = (request: Request): boolean => {
|
||||
if (!new Set(['get', 'post', 'put', 'delete', 'patch']).has(request.method.toLowerCase())) {
|
||||
return false
|
||||
}
|
||||
return !request.multipartUploads && !request.insecure
|
||||
}
|
||||
|
||||
const parseWebOptions = (request) => {
|
||||
const options = {}
|
||||
const parseWebOptions = (request: Request): {[key: string]: string} => {
|
||||
const options: {[key: string]: string} = {}
|
||||
|
||||
// MATLAB uses GET in `webread` and POST in `webwrite` by default
|
||||
// thus, it is necessary to set the method for other requests
|
||||
@@ -21,7 +22,7 @@ const parseWebOptions = (request) => {
|
||||
options.RequestMethod = request.method.toLowerCase()
|
||||
}
|
||||
|
||||
const headers = {}
|
||||
const headers: {[key: string]: string} = {}
|
||||
if (request.auth) {
|
||||
const [username, password] = request.auth
|
||||
if (username !== '') {
|
||||
@@ -34,6 +35,9 @@ const parseWebOptions = (request) => {
|
||||
|
||||
if (request.headers) {
|
||||
for (const [key, value] of request.headers) {
|
||||
if (value === null) {
|
||||
continue
|
||||
}
|
||||
switch (key) {
|
||||
case 'User-Agent':
|
||||
case 'user-agent':
|
||||
@@ -98,8 +102,8 @@ const parseWebOptions = (request) => {
|
||||
return options
|
||||
}
|
||||
|
||||
const prepareOptions = (request, options) => {
|
||||
const lines = []
|
||||
const prepareOptions = (request: Request, options: {[key: string]: string}): string[] => {
|
||||
const lines: string[] = []
|
||||
if (Object.keys(options).length === 0) {
|
||||
return lines
|
||||
}
|
||||
@@ -109,7 +113,7 @@ const prepareOptions = (request, options) => {
|
||||
return lines
|
||||
}
|
||||
|
||||
const prepareBasicURI = (request) => {
|
||||
const prepareBasicURI = (request: Request): string[] => {
|
||||
const response = []
|
||||
if (request.queryDict) {
|
||||
response.push(setVariableValue('baseURI', repr(request.urlWithoutQuery)))
|
||||
@@ -120,8 +124,8 @@ const prepareBasicURI = (request) => {
|
||||
return response
|
||||
}
|
||||
|
||||
const prepareBasicData = (request) => {
|
||||
let response = []
|
||||
const prepareBasicData = (request: Request): string | string[] => {
|
||||
let response: string | string[] = []
|
||||
if (Object.prototype.hasOwnProperty.call(request, 'data')) {
|
||||
if (request.data === '') {
|
||||
response = setVariableValue('body', repr())
|
||||
@@ -151,7 +155,7 @@ const prepareBasicData = (request) => {
|
||||
return response
|
||||
}
|
||||
|
||||
const prepareWebCall = (request, options) => {
|
||||
const prepareWebCall = (request: Request, options: {[key: string]: string}): string[] => {
|
||||
const lines = []
|
||||
const webFunction = containsBody(request) ? 'webwrite' : 'webread'
|
||||
|
||||
@@ -167,8 +171,8 @@ const prepareWebCall = (request, options) => {
|
||||
return lines
|
||||
}
|
||||
|
||||
export const toWebServices = (request) => {
|
||||
let lines = [
|
||||
export const toWebServices = (request: Request): (string | string[] | null)[] => {
|
||||
let lines: (string | string[] | null)[] = [
|
||||
'%% Web Access using Data Import and Export API'
|
||||
]
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
import * as util from '../../util.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
import querystring from 'query-string'
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
const quote = str => jsesc(str, { quotes: 'single' })
|
||||
// TODO: only string
|
||||
const quote = (str: string | null | (string | null)[]): string => jsesc(str, { quotes: 'single' })
|
||||
|
||||
export const _toPhpRequests = request => {
|
||||
let headerString = false
|
||||
export const _toPhpRequests = (request: Request): string => {
|
||||
let headerString: string
|
||||
if (request.headers) {
|
||||
headerString = '$headers = array(\n'
|
||||
let i = 0
|
||||
const headerCount = request.headers ? request.headers.length : 0
|
||||
for (const [headerName, headerValue] of request.headers) {
|
||||
if (headerValue === null) {
|
||||
continue // TODO: this could miss not adding a trailing comma
|
||||
}
|
||||
headerString += " '" + headerName + "' => '" + quote(headerValue) + "'"
|
||||
if (i < headerCount - 1) {
|
||||
headerString += ',\n'
|
||||
@@ -23,13 +28,13 @@ export const _toPhpRequests = request => {
|
||||
headerString = '$headers = array();'
|
||||
}
|
||||
|
||||
let optionsString = false
|
||||
let optionsString
|
||||
if (request.auth) {
|
||||
const [user, password] = request.auth
|
||||
optionsString = "$options = array('auth' => array('" + user + "', '" + password + "'));"
|
||||
}
|
||||
|
||||
let dataString = false
|
||||
let dataString
|
||||
if (request.data) {
|
||||
const parsedQueryString = querystring.parse(request.data, { sort: false })
|
||||
dataString = '$data = array(\n'
|
||||
@@ -74,7 +79,7 @@ export const _toPhpRequests = request => {
|
||||
|
||||
return phpCode + '\n'
|
||||
}
|
||||
export const toPhpRequests = curlCommand => {
|
||||
export const toPhpRequests = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toPhpRequests(request)
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
import * as util from '../../util.js'
|
||||
import type { Request} from '../../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
const quote = str => jsesc(str, { quotes: 'single' })
|
||||
const quote = (str: string): string => jsesc(str, { quotes: 'single' })
|
||||
|
||||
export const _toPhp = request => {
|
||||
export const _toPhp = (request: Request): string => {
|
||||
let cookieString
|
||||
if (util.hasHeader(request, 'cookie')) {
|
||||
cookieString = util.getHeader(request, 'cookie')
|
||||
@@ -30,6 +32,9 @@ export const _toPhp = request => {
|
||||
}
|
||||
|
||||
for (const [headerName, headerValue] of (request.headers || [])) {
|
||||
if (headerValue === null) {
|
||||
continue
|
||||
}
|
||||
headersArrayCode += " '" + quote(headerName) + "' => '" + quote(headerValue) + "',\n"
|
||||
}
|
||||
|
||||
@@ -93,7 +98,7 @@ export const _toPhp = request => {
|
||||
return phpCode
|
||||
}
|
||||
|
||||
export const toPhp = curlCommand => {
|
||||
export const toPhp = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toPhp(request)
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as util from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
import type { Request, Query, QueryDict } from '../util.js'
|
||||
|
||||
function reprWithVariable (value, hasEnvironmentVariable) {
|
||||
function reprWithVariable (value: string, hasEnvironmentVariable: boolean) {
|
||||
if (!value) {
|
||||
return "''"
|
||||
}
|
||||
@@ -14,12 +15,12 @@ function reprWithVariable (value, hasEnvironmentVariable) {
|
||||
return 'f"' + jsesc(value, { quotes: 'double' }) + '"'
|
||||
}
|
||||
|
||||
function repr (value) {
|
||||
function repr (value: string): string {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
return reprWithVariable(value, false)
|
||||
}
|
||||
|
||||
function objToPython (obj, indent = 0) {
|
||||
function objToPython (obj: any, indent = 0): string {
|
||||
let s = ''
|
||||
switch (typeof obj) {
|
||||
case 'string':
|
||||
@@ -64,7 +65,7 @@ function objToPython (obj, indent = 0) {
|
||||
return s
|
||||
}
|
||||
|
||||
function objToDictOrListOfTuples (obj) {
|
||||
function objToDictOrListOfTuples (obj: Query | QueryDict): string {
|
||||
if (!Array.isArray(obj)) {
|
||||
return objToPython(obj)
|
||||
}
|
||||
@@ -79,7 +80,7 @@ function objToDictOrListOfTuples (obj) {
|
||||
return s
|
||||
}
|
||||
|
||||
function getDataString (request) {
|
||||
function getDataString (request: Request) {
|
||||
if (!request.isDataRaw && request.data.startsWith('@')) {
|
||||
let filePath = request.data.slice(1)
|
||||
if (filePath === '-') {
|
||||
@@ -106,8 +107,8 @@ function getDataString (request) {
|
||||
|
||||
const dataString = 'data = ' + repr(request.data) + '\n'
|
||||
|
||||
const isJson = util.hasHeader(request, 'content-type') &&
|
||||
util.getHeader(request, 'content-type').split(';')[0].trim() === 'application/json'
|
||||
const contentTypeHeader = util.getHeader(request, 'content-type')
|
||||
const isJson = contentTypeHeader && contentTypeHeader.split(';')[0].trim() === 'application/json'
|
||||
if (isJson) {
|
||||
try {
|
||||
const dataAsJson = JSON.parse(request.data)
|
||||
@@ -136,7 +137,10 @@ function getDataString (request) {
|
||||
return [dataString, null, null]
|
||||
}
|
||||
|
||||
function getFilesString (request) {
|
||||
function getFilesString (request: Request): string | undefined {
|
||||
if (!request.multipartUploads) {
|
||||
return undefined
|
||||
}
|
||||
const multipartUploads = request.multipartUploads.map(m => {
|
||||
let multipartValue
|
||||
if (m[1].startsWith('@')) {
|
||||
@@ -170,7 +174,7 @@ function getFilesString (request) {
|
||||
|
||||
// convertVarToStringFormat will convert if inputString to f"..." format
|
||||
// if inputString has possible variable as its substring
|
||||
function detectEnvVar (inputString) {
|
||||
function detectEnvVar (inputString: string): [Set<string>, string] {
|
||||
// Using state machine to detect environment variable
|
||||
// Each character is an edge, state machine:
|
||||
// IN_ENV_VAR: means that currently we are iterating inside a possible environment variable
|
||||
@@ -184,15 +188,15 @@ function detectEnvVar (inputString) {
|
||||
const IN_STRING = 1
|
||||
|
||||
// We only care for the unique element
|
||||
const detectedVariables = new Set()
|
||||
const detectedVariables: Set<string> = new Set()
|
||||
let currState = IN_STRING
|
||||
let envVarStartIndex = -1
|
||||
|
||||
const whiteSpaceSet = new Set(' \n\t')
|
||||
|
||||
const modifiedString = []
|
||||
for (const idx in inputString) {
|
||||
const currIdx = +idx
|
||||
for (let idx = 0; idx < inputString.length; idx++) {
|
||||
const currIdx = idx
|
||||
const currChar = inputString[currIdx]
|
||||
if (currState === IN_ENV_VAR && whiteSpaceSet.has(currChar)) {
|
||||
const newVariable = inputString.substring(envVarStartIndex, currIdx)
|
||||
@@ -239,11 +243,11 @@ function detectEnvVar (inputString) {
|
||||
return [detectedVariables, modifiedString.join('')]
|
||||
}
|
||||
|
||||
export const _toPython = request => {
|
||||
export const _toPython = (request: Request): string => {
|
||||
// Currently, only assuming that the env-var only used in
|
||||
// the value part of cookies, params, or body
|
||||
const osVariables = new Set()
|
||||
const commentedOutHeaders = {
|
||||
const commentedOutHeaders: {[key: string]: string} = {
|
||||
'accept-encoding': '',
|
||||
'content-length': ''
|
||||
}
|
||||
@@ -317,6 +321,7 @@ export const _toPython = request => {
|
||||
queryStr = 'params = ' + objToDictOrListOfTuples(request.queryDict || request.query) + '\n'
|
||||
}
|
||||
|
||||
const contentType = util.getHeader(request, 'content-type')
|
||||
let dataString
|
||||
let jsonDataString
|
||||
let jsonDataStringRoundtrips
|
||||
@@ -325,7 +330,7 @@ export const _toPython = request => {
|
||||
[dataString, jsonDataString, jsonDataStringRoundtrips] = getDataString(request)
|
||||
// Remove "Content-Type" from the headers dict
|
||||
// because Requests adds it automatically when you use json=
|
||||
if (jsonDataString && util.getHeader(request, 'content-type').trim() === 'application/json') {
|
||||
if (jsonDataString && contentType && contentType.trim() === 'application/json') {
|
||||
commentedOutHeaders['content-type'] = 'Already added when you pass json='
|
||||
if (!jsonDataStringRoundtrips) {
|
||||
commentedOutHeaders['content-type'] += ' but not when you pass data='
|
||||
@@ -338,9 +343,9 @@ export const _toPython = request => {
|
||||
// wheras curl does, so the request will fail.
|
||||
// https://github.com/curlconverter/curlconverter/issues/248
|
||||
if (filesString &&
|
||||
util.hasHeader(request, 'content-type') &&
|
||||
util.getHeader(request, 'content-type').trim() === 'multipart/form-data' &&
|
||||
!util.getHeader(request, 'content-type').includes('boundary=')) {
|
||||
contentType &&
|
||||
contentType.trim() === 'multipart/form-data' &&
|
||||
!contentType.includes('boundary=')) {
|
||||
// TODO: better wording
|
||||
commentedOutHeaders['content-type'] = "requests won't add a boundary if this header is set when you pass files="
|
||||
}
|
||||
@@ -351,6 +356,9 @@ export const _toPython = request => {
|
||||
// TODO: what if there are repeat headers
|
||||
headerDict = 'headers = {\n'
|
||||
for (const [headerName, headerValue] of request.headers) {
|
||||
if (headerValue === null) {
|
||||
continue
|
||||
}
|
||||
const [detectedVars, modifiedString] = detectEnvVar(headerValue)
|
||||
|
||||
const hasVariable = detectedVars.size > 0
|
||||
@@ -502,7 +510,7 @@ export const _toPython = request => {
|
||||
|
||||
return pythonCode + '\n'
|
||||
}
|
||||
export const toPython = curlCommand => {
|
||||
export const toPython = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toPython(request)
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
// Author: Bob Rudis (bob@rud.is)
|
||||
|
||||
import * as util from '../util.js'
|
||||
import type { Request, Cookie, QueryDict } from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
import querystring from 'query-string'
|
||||
|
||||
function reprn (value) { // back-tick quote names
|
||||
function reprn (value: string | null): string { // back-tick quote names
|
||||
if (!value) {
|
||||
return '``'
|
||||
} else {
|
||||
@@ -13,7 +14,7 @@ function reprn (value) { // back-tick quote names
|
||||
}
|
||||
}
|
||||
|
||||
function repr (value) {
|
||||
function repr (value: string): string {
|
||||
// In context of url parameters, don't accept nulls and such.
|
||||
if (!value) {
|
||||
return "''"
|
||||
@@ -22,15 +23,19 @@ function repr (value) {
|
||||
}
|
||||
}
|
||||
|
||||
function getQueryDict (request) {
|
||||
function getQueryDict (request: Request): string | undefined {
|
||||
if (request.queryDict === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
let queryDict = 'params = list(\n'
|
||||
queryDict += Object.keys(request.queryDict).map((paramName) => {
|
||||
const rawValue = request.queryDict[paramName]
|
||||
const rawValue = (request.queryDict as QueryDict)[paramName]
|
||||
let paramValue
|
||||
if (Array.isArray(rawValue)) {
|
||||
paramValue = 'c(' + rawValue.map(repr).join(', ') + ')'
|
||||
paramValue = 'c(' + (rawValue as string[]).map(repr).join(', ') + ')'
|
||||
} else {
|
||||
paramValue = repr(rawValue)
|
||||
paramValue = repr(rawValue as string)
|
||||
}
|
||||
return (' ' + reprn(paramName) + ' = ' + paramValue)
|
||||
}).join(',\n')
|
||||
@@ -38,7 +43,7 @@ function getQueryDict (request) {
|
||||
return queryDict
|
||||
}
|
||||
|
||||
function getDataString (request) {
|
||||
function getDataString (request: Request) {
|
||||
if (!request.isDataRaw && request.data.startsWith('@')) {
|
||||
const filePath = request.data.slice(1)
|
||||
return 'data = upload_file(\'' + filePath + '\')'
|
||||
@@ -55,7 +60,7 @@ function getDataString (request) {
|
||||
}
|
||||
}
|
||||
|
||||
function getMultipleDataString (request, parsedQueryString) {
|
||||
function getMultipleDataString (request: Request, parsedQueryString: querystring.ParsedQuery<string> ) {
|
||||
let repeatedKey = false
|
||||
for (const key in parsedQueryString) {
|
||||
const value = parsedQueryString[key]
|
||||
@@ -72,10 +77,11 @@ function getMultipleDataString (request, parsedQueryString) {
|
||||
const value = parsedQueryString[key]
|
||||
if (Array.isArray(value)) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
els.push(' ' + reprn(key) + ' = ' + repr(value[i]))
|
||||
const val = value[i]
|
||||
els.push(' ' + reprn(key) + ' = ' + repr(val === null ? '' : val))
|
||||
}
|
||||
} else {
|
||||
els.push(' ' + reprn(key) + ' = ' + repr(value))
|
||||
els.push(' ' + reprn(key) + ' = ' + repr(value === null ? '' : value))
|
||||
}
|
||||
}
|
||||
dataString += els.join(',\n')
|
||||
@@ -84,7 +90,7 @@ function getMultipleDataString (request, parsedQueryString) {
|
||||
dataString = 'data = list(\n'
|
||||
dataString += Object.keys(parsedQueryString).map((key) => {
|
||||
const value = parsedQueryString[key]
|
||||
return (' ' + reprn(key) + ' = ' + repr(value))
|
||||
return (' ' + reprn(key) + ' = ' + repr(value === null ? '' : value as string))
|
||||
}).join(',\n')
|
||||
dataString += '\n)\n'
|
||||
}
|
||||
@@ -92,7 +98,10 @@ function getMultipleDataString (request, parsedQueryString) {
|
||||
return dataString
|
||||
}
|
||||
|
||||
function getFilesString (request) {
|
||||
function getFilesString (request: Request): string | undefined {
|
||||
if (!request.multipartUploads) {
|
||||
return undefined
|
||||
}
|
||||
// http://docs.rstats-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
|
||||
let filesString = 'files = list(\n'
|
||||
filesString += request.multipartUploads.map((m) => {
|
||||
@@ -112,11 +121,11 @@ function getFilesString (request) {
|
||||
return filesString
|
||||
}
|
||||
|
||||
export const _toR = request => {
|
||||
export const _toR = (request: Request) => {
|
||||
let cookieDict
|
||||
if (request.cookies) {
|
||||
cookieDict = 'cookies = c(\n'
|
||||
cookieDict += request.cookies.map(c => ' ' + repr(c[0]) + ' = ' + repr(c[1])).join(',\n')
|
||||
cookieDict += request.cookies.map((c: Cookie) => ' ' + repr(c[0]) + ' = ' + repr(c[1])).join(',\n')
|
||||
// TODO: isn't this an extra \n?
|
||||
cookieDict += '\n)\n'
|
||||
util.deleteHeader(request, 'Cookie')
|
||||
@@ -126,16 +135,15 @@ export const _toR = request => {
|
||||
const hels = []
|
||||
headerDict = 'headers = c(\n'
|
||||
for (const [headerName, headerValue] of request.headers) {
|
||||
hels.push(' ' + reprn(headerName) + ' = ' + repr(headerValue))
|
||||
if (headerValue !== null) {
|
||||
hels.push(' ' + reprn(headerName) + ' = ' + repr(headerValue))
|
||||
}
|
||||
}
|
||||
headerDict += hels.join(',\n')
|
||||
headerDict += '\n)\n'
|
||||
}
|
||||
|
||||
let queryDict
|
||||
if (request.queryDict) {
|
||||
queryDict = getQueryDict(request)
|
||||
}
|
||||
const queryDict = getQueryDict(request)
|
||||
|
||||
let dataString
|
||||
let filesString
|
||||
@@ -189,7 +197,7 @@ export const _toR = request => {
|
||||
if (headerDict) {
|
||||
rstatsCode += headerDict + '\n'
|
||||
}
|
||||
if (queryDict) {
|
||||
if (queryDict !== undefined) {
|
||||
rstatsCode += queryDict + '\n'
|
||||
}
|
||||
if (dataString) {
|
||||
@@ -201,7 +209,7 @@ export const _toR = request => {
|
||||
|
||||
return rstatsCode + '\n'
|
||||
}
|
||||
export const toR = curlCommand => {
|
||||
export const toR = (curlCommand: string | string[]): string => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toR(request)
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request } from '../util.js'
|
||||
|
||||
import jsesc from 'jsesc'
|
||||
|
||||
const INDENTATION = ' '.repeat(4)
|
||||
const indent = (line, level = 1) => INDENTATION.repeat(level) + line
|
||||
const quote = str => jsesc(str, { quotes: 'double' })
|
||||
const indent = (line:string, level = 1): string => INDENTATION.repeat(level) + line
|
||||
const quote = (str: string): string => jsesc(str, { quotes: 'double' })
|
||||
|
||||
export const _toRust = request => {
|
||||
export const _toRust = (request: Request) => {
|
||||
const lines = ['extern crate reqwest;']
|
||||
{
|
||||
// Generate imports.
|
||||
@@ -25,13 +26,15 @@ export const _toRust = request => {
|
||||
|
||||
if (request.headers) {
|
||||
lines.push(indent('let mut headers = header::HeaderMap::new();'))
|
||||
const headerEnum = {
|
||||
const headerEnum: { [key: string]: string } = {
|
||||
cookie: 'header::COOKIE'
|
||||
}
|
||||
for (const [headerName, headerValue] of (request.headers || [])) {
|
||||
const enumValue = headerEnum[headerName.toLowerCase()]
|
||||
const name = enumValue || `"${headerName}"`
|
||||
lines.push(indent(`headers.insert(${name}, "${quote(headerValue)}".parse().unwrap());`))
|
||||
if (headerValue !== null) {
|
||||
lines.push(indent(`headers.insert(${name}, "${quote(headerValue)}".parse().unwrap());`))
|
||||
}
|
||||
}
|
||||
lines.push('')
|
||||
}
|
||||
@@ -95,7 +98,7 @@ export const _toRust = request => {
|
||||
|
||||
return lines.join('\n') + '\n'
|
||||
}
|
||||
export const toRust = curlCommand => {
|
||||
export const toRust = (curlCommand: string | string[]) => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toRust(request)
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as util from '../util.js'
|
||||
import type { Request } from '../util.js'
|
||||
|
||||
import yaml from 'yamljs'
|
||||
import jsesc from 'jsesc'
|
||||
import querystring from 'query-string'
|
||||
|
||||
function getDataString (request) {
|
||||
function getDataString (request: Request) {
|
||||
let mimeType = 'application/json'
|
||||
if (request.data.indexOf("'") > -1) {
|
||||
request.data = jsesc(request.data)
|
||||
@@ -24,7 +25,7 @@ function getDataString (request) {
|
||||
}
|
||||
|
||||
for (const [paramName, paramValue] of (request.headers || [])) {
|
||||
if (paramName === 'Content-Type') {
|
||||
if (paramName.toLowerCase() === 'content-type' && paramValue !== null) {
|
||||
mimeType = paramValue
|
||||
}
|
||||
}
|
||||
@@ -34,13 +35,8 @@ function getDataString (request) {
|
||||
}
|
||||
}
|
||||
|
||||
function getQueryList (request) {
|
||||
// Convert nulls to empty string
|
||||
return request.query.map(p => ({ name: p[0], value: p[1] || '' }))
|
||||
}
|
||||
|
||||
export const _toStrest = request => {
|
||||
const response = { version: 2 }
|
||||
export const _toStrest = (request: Request) => {
|
||||
const response: {[key: string]: any} = { version: 2 }
|
||||
if (request.insecure) {
|
||||
response.allowInsecure = true
|
||||
}
|
||||
@@ -70,7 +66,7 @@ export const _toStrest = request => {
|
||||
}
|
||||
if (request.auth) {
|
||||
const [username, password] = request.auth
|
||||
const basic = {}
|
||||
const basic: {[key: string]: string} = {}
|
||||
if (username) {
|
||||
basic.username = username
|
||||
}
|
||||
@@ -80,14 +76,15 @@ export const _toStrest = request => {
|
||||
|
||||
let queryList
|
||||
if (request.query) {
|
||||
queryList = getQueryList(request)
|
||||
// Convert nulls to empty string
|
||||
queryList = request.query.map((p) => ({ name: p[0], value: p[1] || '' }))
|
||||
response.requests.curl_converter.request.queryString = queryList
|
||||
}
|
||||
|
||||
const yamlString = yaml.stringify(response, 100, 2)
|
||||
return yamlString
|
||||
}
|
||||
export const toStrest = curlCommand => {
|
||||
export const toStrest = (curlCommand: string | string[]) => {
|
||||
const request = util.parseCurlCommand(curlCommand)
|
||||
return _toStrest(request)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user