@ohos-ports/curlconverter 4.12.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/src/Headers.d.ts +23 -0
- package/dist/src/Headers.js +287 -0
- package/dist/src/Headers.js.map +1 -0
- package/dist/src/Query.d.ts +8 -0
- package/dist/src/Query.js +136 -0
- package/dist/src/Query.js.map +1 -0
- package/dist/src/Request.d.ts +200 -0
- package/dist/src/Request.js +1191 -0
- package/dist/src/Request.js.map +1 -0
- package/dist/src/Warnings.d.ts +15 -0
- package/dist/src/Warnings.js +111 -0
- package/dist/src/Warnings.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +333 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/curl/auth.d.ts +12 -0
- package/dist/src/curl/auth.js +40 -0
- package/dist/src/curl/auth.js.map +1 -0
- package/dist/src/curl/form.d.ts +28 -0
- package/dist/src/curl/form.js +218 -0
- package/dist/src/curl/form.js.map +1 -0
- package/dist/src/curl/opts.d.ts +2052 -0
- package/dist/src/curl/opts.js +1000 -0
- package/dist/src/curl/opts.js.map +1 -0
- package/dist/src/curl/url.d.ts +14 -0
- package/dist/src/curl/url.js +218 -0
- package/dist/src/curl/url.js.map +1 -0
- package/dist/src/generators/ansible.d.ts +5 -0
- package/dist/src/generators/ansible.js +282 -0
- package/dist/src/generators/ansible.js.map +1 -0
- package/dist/src/generators/c.d.ts +12 -0
- package/dist/src/generators/c.js +1230 -0
- package/dist/src/generators/c.js.map +1 -0
- package/dist/src/generators/cfml.d.ts +5 -0
- package/dist/src/generators/cfml.js +134 -0
- package/dist/src/generators/cfml.js.map +1 -0
- package/dist/src/generators/clojure.d.ts +7 -0
- package/dist/src/generators/clojure.js +436 -0
- package/dist/src/generators/clojure.js.map +1 -0
- package/dist/src/generators/csharp.d.ts +8 -0
- package/dist/src/generators/csharp.js +356 -0
- package/dist/src/generators/csharp.js.map +1 -0
- package/dist/src/generators/dart.d.ts +5 -0
- package/dist/src/generators/dart.js +273 -0
- package/dist/src/generators/dart.js.map +1 -0
- package/dist/src/generators/elixir.d.ts +8 -0
- package/dist/src/generators/elixir.js +296 -0
- package/dist/src/generators/elixir.js.map +1 -0
- package/dist/src/generators/go.d.ts +5 -0
- package/dist/src/generators/go.js +228 -0
- package/dist/src/generators/go.js.map +1 -0
- package/dist/src/generators/har.d.ts +7 -0
- package/dist/src/generators/har.js +115 -0
- package/dist/src/generators/har.js.map +1 -0
- package/dist/src/generators/http.d.ts +7 -0
- package/dist/src/generators/http.js +165 -0
- package/dist/src/generators/http.js.map +1 -0
- package/dist/src/generators/httpie.d.ts +5 -0
- package/dist/src/generators/httpie.js +446 -0
- package/dist/src/generators/httpie.js.map +1 -0
- package/dist/src/generators/java/httpurlconnection.d.ts +5 -0
- package/dist/src/generators/java/httpurlconnection.js +123 -0
- package/dist/src/generators/java/httpurlconnection.js.map +1 -0
- package/dist/src/generators/java/java.d.ts +8 -0
- package/dist/src/generators/java/java.js +247 -0
- package/dist/src/generators/java/java.js.map +1 -0
- package/dist/src/generators/java/jsoup.d.ts +5 -0
- package/dist/src/generators/java/jsoup.js +152 -0
- package/dist/src/generators/java/jsoup.js.map +1 -0
- package/dist/src/generators/java/okhttp.d.ts +5 -0
- package/dist/src/generators/java/okhttp.js +232 -0
- package/dist/src/generators/java/okhttp.js.map +1 -0
- package/dist/src/generators/javascript/axios.d.ts +5 -0
- package/dist/src/generators/javascript/axios.js +332 -0
- package/dist/src/generators/javascript/axios.js.map +1 -0
- package/dist/src/generators/javascript/got.d.ts +5 -0
- package/dist/src/generators/javascript/got.js +277 -0
- package/dist/src/generators/javascript/got.js.map +1 -0
- package/dist/src/generators/javascript/http.d.ts +8 -0
- package/dist/src/generators/javascript/http.js +183 -0
- package/dist/src/generators/javascript/http.js.map +1 -0
- package/dist/src/generators/javascript/javascript.d.ts +37 -0
- package/dist/src/generators/javascript/javascript.js +676 -0
- package/dist/src/generators/javascript/javascript.js.map +1 -0
- package/dist/src/generators/javascript/jquery.d.ts +15 -0
- package/dist/src/generators/javascript/jquery.js +297 -0
- package/dist/src/generators/javascript/jquery.js.map +1 -0
- package/dist/src/generators/javascript/ky.d.ts +7 -0
- package/dist/src/generators/javascript/ky.js +245 -0
- package/dist/src/generators/javascript/ky.js.map +1 -0
- package/dist/src/generators/javascript/request.d.ts +5 -0
- package/dist/src/generators/javascript/request.js +113 -0
- package/dist/src/generators/javascript/request.js.map +1 -0
- package/dist/src/generators/javascript/superagent.d.ts +10 -0
- package/dist/src/generators/javascript/superagent.js +301 -0
- package/dist/src/generators/javascript/superagent.js.map +1 -0
- package/dist/src/generators/javascript/xhr.d.ts +8 -0
- package/dist/src/generators/javascript/xhr.js +147 -0
- package/dist/src/generators/javascript/xhr.js.map +1 -0
- package/dist/src/generators/json.d.ts +45 -0
- package/dist/src/generators/json.js +197 -0
- package/dist/src/generators/json.js.map +1 -0
- package/dist/src/generators/julia.d.ts +8 -0
- package/dist/src/generators/julia.js +365 -0
- package/dist/src/generators/julia.js.map +1 -0
- package/dist/src/generators/kotlin.d.ts +8 -0
- package/dist/src/generators/kotlin.js +325 -0
- package/dist/src/generators/kotlin.js.map +1 -0
- package/dist/src/generators/lua.d.ts +5 -0
- package/dist/src/generators/lua.js +192 -0
- package/dist/src/generators/lua.js.map +1 -0
- package/dist/src/generators/matlab/common.d.ts +16 -0
- package/dist/src/generators/matlab/common.js +238 -0
- package/dist/src/generators/matlab/common.js.map +1 -0
- package/dist/src/generators/matlab/httpinterface.d.ts +2 -0
- package/dist/src/generators/matlab/httpinterface.js +211 -0
- package/dist/src/generators/matlab/httpinterface.js.map +1 -0
- package/dist/src/generators/matlab/matlab.d.ts +5 -0
- package/dist/src/generators/matlab/matlab.js +29 -0
- package/dist/src/generators/matlab/matlab.js.map +1 -0
- package/dist/src/generators/matlab/webservices.d.ts +2 -0
- package/dist/src/generators/matlab/webservices.js +191 -0
- package/dist/src/generators/matlab/webservices.js.map +1 -0
- package/dist/src/generators/objectivec.d.ts +8 -0
- package/dist/src/generators/objectivec.js +269 -0
- package/dist/src/generators/objectivec.js.map +1 -0
- package/dist/src/generators/ocaml.d.ts +8 -0
- package/dist/src/generators/ocaml.js +150 -0
- package/dist/src/generators/ocaml.js.map +1 -0
- package/dist/src/generators/perl.d.ts +9 -0
- package/dist/src/generators/perl.js +209 -0
- package/dist/src/generators/perl.js.map +1 -0
- package/dist/src/generators/php/guzzle.d.ts +5 -0
- package/dist/src/generators/php/guzzle.js +328 -0
- package/dist/src/generators/php/guzzle.js.map +1 -0
- package/dist/src/generators/php/php.d.ts +8 -0
- package/dist/src/generators/php/php.js +217 -0
- package/dist/src/generators/php/php.js.map +1 -0
- package/dist/src/generators/php/requests.d.ts +5 -0
- package/dist/src/generators/php/requests.js +89 -0
- package/dist/src/generators/php/requests.js.map +1 -0
- package/dist/src/generators/powershell.d.ts +11 -0
- package/dist/src/generators/powershell.js +377 -0
- package/dist/src/generators/powershell.js.map +1 -0
- package/dist/src/generators/python/http.d.ts +5 -0
- package/dist/src/generators/python/http.js +128 -0
- package/dist/src/generators/python/http.js.map +1 -0
- package/dist/src/generators/python/python.d.ts +22 -0
- package/dist/src/generators/python/python.js +1693 -0
- package/dist/src/generators/python/python.js.map +1 -0
- package/dist/src/generators/r/httr.d.ts +10 -0
- package/dist/src/generators/r/httr.js +298 -0
- package/dist/src/generators/r/httr.js.map +1 -0
- package/dist/src/generators/r/httr2.d.ts +5 -0
- package/dist/src/generators/r/httr2.js +214 -0
- package/dist/src/generators/r/httr2.js.map +1 -0
- package/dist/src/generators/ruby/httparty.d.ts +6 -0
- package/dist/src/generators/ruby/httparty.js +308 -0
- package/dist/src/generators/ruby/httparty.js.map +1 -0
- package/dist/src/generators/ruby/ruby.d.ts +14 -0
- package/dist/src/generators/ruby/ruby.js +515 -0
- package/dist/src/generators/ruby/ruby.js.map +1 -0
- package/dist/src/generators/rust.d.ts +8 -0
- package/dist/src/generators/rust.js +177 -0
- package/dist/src/generators/rust.js.map +1 -0
- package/dist/src/generators/swift.d.ts +8 -0
- package/dist/src/generators/swift.js +219 -0
- package/dist/src/generators/swift.js.map +1 -0
- package/dist/src/generators/wget.d.ts +8 -0
- package/dist/src/generators/wget.js +472 -0
- package/dist/src/generators/wget.js.map +1 -0
- package/dist/src/index.d.ts +53 -0
- package/dist/src/index.js +54 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/parse.d.ts +13 -0
- package/dist/src/parse.js +43 -0
- package/dist/src/parse.js.map +1 -0
- package/dist/src/shell/Parser.d.ts +4 -0
- package/dist/src/shell/Parser.js +6 -0
- package/dist/src/shell/Parser.js.map +1 -0
- package/dist/src/shell/Word.d.ts +48 -0
- package/dist/src/shell/Word.js +486 -0
- package/dist/src/shell/Word.js.map +1 -0
- package/dist/src/shell/tokenizer.d.ts +3 -0
- package/dist/src/shell/tokenizer.js +610 -0
- package/dist/src/shell/tokenizer.js.map +1 -0
- package/dist/src/shell/webParser.d.ts +4 -0
- package/dist/src/shell/webParser.js +15 -0
- package/dist/src/shell/webParser.js.map +1 -0
- package/dist/src/utils.d.ts +6 -0
- package/dist/src/utils.js +21 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/tools/compare-requests.d.ts +2 -0
- package/dist/tools/compare-requests.js +448 -0
- package/dist/tools/compare-requests.js.map +1 -0
- package/dist/tools/gen-test.d.ts +2 -0
- package/dist/tools/gen-test.js +114 -0
- package/dist/tools/gen-test.js.map +1 -0
- package/dist/tree-sitter-bash.wasm +0 -0
- package/index.d.ts +3 -0
- package/package.json +97 -0
- package/src/Headers.ts +334 -0
- package/src/Query.ts +147 -0
- package/src/Request.ts +1649 -0
- package/src/Warnings.ts +154 -0
- package/src/cli.ts +561 -0
- package/src/curl/auth.ts +45 -0
- package/src/curl/form.ts +297 -0
- package/src/curl/opts.ts +1417 -0
- package/src/curl/url.ts +241 -0
- package/src/generators/ansible.ts +364 -0
- package/src/generators/c.ts +1371 -0
- package/src/generators/cfml.ts +155 -0
- package/src/generators/clojure.ts +521 -0
- package/src/generators/csharp.ts +383 -0
- package/src/generators/dart.ts +293 -0
- package/src/generators/elixir.ts +349 -0
- package/src/generators/go.ts +269 -0
- package/src/generators/har.ts +147 -0
- package/src/generators/http.ts +194 -0
- package/src/generators/httpie.ts +506 -0
- package/src/generators/java/httpurlconnection.ts +151 -0
- package/src/generators/java/java.ts +280 -0
- package/src/generators/java/jsoup.ts +172 -0
- package/src/generators/java/okhttp.ts +257 -0
- package/src/generators/javascript/axios.ts +395 -0
- package/src/generators/javascript/got.ts +362 -0
- package/src/generators/javascript/http.ts +232 -0
- package/src/generators/javascript/javascript.ts +825 -0
- package/src/generators/javascript/jquery.ts +360 -0
- package/src/generators/javascript/ky.ts +315 -0
- package/src/generators/javascript/request.ts +152 -0
- package/src/generators/javascript/superagent.ts +373 -0
- package/src/generators/javascript/xhr.ts +192 -0
- package/src/generators/json.ts +293 -0
- package/src/generators/julia.ts +398 -0
- package/src/generators/kotlin.ts +355 -0
- package/src/generators/lua.ts +209 -0
- package/src/generators/matlab/common.ts +281 -0
- package/src/generators/matlab/httpinterface.ts +284 -0
- package/src/generators/matlab/matlab.ts +39 -0
- package/src/generators/matlab/webservices.ts +263 -0
- package/src/generators/objectivec.ts +297 -0
- package/src/generators/ocaml.ts +168 -0
- package/src/generators/perl.ts +237 -0
- package/src/generators/php/guzzle.ts +368 -0
- package/src/generators/php/php.ts +239 -0
- package/src/generators/php/requests.ts +103 -0
- package/src/generators/powershell.ts +430 -0
- package/src/generators/python/http.ts +167 -0
- package/src/generators/python/python.ts +1934 -0
- package/src/generators/r/httr.ts +328 -0
- package/src/generators/r/httr2.ts +268 -0
- package/src/generators/ruby/httparty.ts +351 -0
- package/src/generators/ruby/ruby.ts +564 -0
- package/src/generators/rust.ts +243 -0
- package/src/generators/swift.ts +235 -0
- package/src/generators/wget.ts +533 -0
- package/src/index.ts +89 -0
- package/src/parse.ts +72 -0
- package/src/shell/Parser.ts +8 -0
- package/src/shell/Word.ts +531 -0
- package/src/shell/tokenizer.ts +736 -0
- package/src/shell/webParser.ts +18 -0
- package/src/utils.ts +25 -0
- package/tools/compare-requests.ts +571 -0
- package/tools/extract_curl_args.py +511 -0
- package/tools/gen-test.ts +129 -0
|
@@ -0,0 +1,825 @@
|
|
|
1
|
+
import { warnIfPartsIgnored } from "../../Warnings.js";
|
|
2
|
+
import { Word, eq, joinWords } from "../../shell/Word.js";
|
|
3
|
+
import { parse, COMMON_SUPPORTED_ARGS } from "../../parse.js";
|
|
4
|
+
import type { Request, Warnings } from "../../parse.js";
|
|
5
|
+
import { parseQueryString } from "../../Query.js";
|
|
6
|
+
import type { QueryList, QueryDict } from "../../Query.js";
|
|
7
|
+
import type { FormParam } from "../../curl/form.js";
|
|
8
|
+
|
|
9
|
+
import jsescObj from "jsesc";
|
|
10
|
+
|
|
11
|
+
export const javaScriptSupportedArgs = new Set([
|
|
12
|
+
...COMMON_SUPPORTED_ARGS,
|
|
13
|
+
"upload-file",
|
|
14
|
+
"form",
|
|
15
|
+
"form-string",
|
|
16
|
+
"digest",
|
|
17
|
+
"no-digest",
|
|
18
|
+
"next",
|
|
19
|
+
|
|
20
|
+
// --no-compressed (the default) is unsupported though
|
|
21
|
+
"compressed",
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
export const nodeSupportedArgs = new Set([...javaScriptSupportedArgs, "proxy"]);
|
|
25
|
+
|
|
26
|
+
// https://fetch.spec.whatwg.org/#forbidden-method
|
|
27
|
+
export const FORBIDDEN_METHODS = ["CONNECT", "TRACE", "TRACK"];
|
|
28
|
+
// https://fetch.spec.whatwg.org/#forbidden-request-header
|
|
29
|
+
export const FORBIDDEN_HEADERS = [
|
|
30
|
+
"Accept-Charset",
|
|
31
|
+
"Accept-Encoding",
|
|
32
|
+
"Access-Control-Request-Headers",
|
|
33
|
+
"Access-Control-Request-Method",
|
|
34
|
+
"Connection",
|
|
35
|
+
"Content-Length",
|
|
36
|
+
"Cookie",
|
|
37
|
+
"Cookie2",
|
|
38
|
+
"Date",
|
|
39
|
+
"DNT",
|
|
40
|
+
"Expect",
|
|
41
|
+
"Host",
|
|
42
|
+
"Keep-Alive",
|
|
43
|
+
"Origin",
|
|
44
|
+
"Referer",
|
|
45
|
+
"Set-Cookie",
|
|
46
|
+
"TE",
|
|
47
|
+
"Trailer",
|
|
48
|
+
"Transfer-Encoding",
|
|
49
|
+
"Upgrade",
|
|
50
|
+
"Via",
|
|
51
|
+
].map((h) => h.toLowerCase());
|
|
52
|
+
|
|
53
|
+
// TODO: implement?
|
|
54
|
+
export function reprObj(value: object, indentLevel?: number): string {
|
|
55
|
+
const escaped = jsescObj(value, {
|
|
56
|
+
quotes: "single",
|
|
57
|
+
minimal: false,
|
|
58
|
+
compact: false,
|
|
59
|
+
indent: " ",
|
|
60
|
+
indentLevel: indentLevel ? indentLevel : 0,
|
|
61
|
+
});
|
|
62
|
+
if (typeof value === "string") {
|
|
63
|
+
return "'" + escaped + "'";
|
|
64
|
+
}
|
|
65
|
+
return escaped;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function reprPairs(
|
|
69
|
+
d: [Word, Word][],
|
|
70
|
+
indentLevel = 0,
|
|
71
|
+
indent = " ",
|
|
72
|
+
list = true,
|
|
73
|
+
imports: JSImports,
|
|
74
|
+
): string {
|
|
75
|
+
if (d.length === 0) {
|
|
76
|
+
return list ? "[]" : "{}";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let code = list ? "[\n" : "{\n";
|
|
80
|
+
for (const [i, [key, value]] of d.entries()) {
|
|
81
|
+
code += indent.repeat(indentLevel + 1);
|
|
82
|
+
if (list) {
|
|
83
|
+
code += "[" + repr(key, imports) + ", " + repr(value, imports) + "]";
|
|
84
|
+
} else {
|
|
85
|
+
code += repr(key, imports) + ": " + repr(value, imports);
|
|
86
|
+
}
|
|
87
|
+
code += i < d.length - 1 ? ",\n" : "\n";
|
|
88
|
+
}
|
|
89
|
+
code += indent.repeat(indentLevel) + (list ? "]" : "}");
|
|
90
|
+
return code;
|
|
91
|
+
}
|
|
92
|
+
export function reprAsStringToStringDict(
|
|
93
|
+
d: [Word, Word][],
|
|
94
|
+
indentLevel = 0,
|
|
95
|
+
imports: JSImports,
|
|
96
|
+
indent = " ",
|
|
97
|
+
): string {
|
|
98
|
+
return reprPairs(d, indentLevel, indent, false, imports);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function reprAsStringTuples(
|
|
102
|
+
d: [Word, Word][],
|
|
103
|
+
indentLevel = 0,
|
|
104
|
+
imports: JSImports,
|
|
105
|
+
indent = " ",
|
|
106
|
+
): string {
|
|
107
|
+
return reprPairs(d, indentLevel, indent, true, imports);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function reprStringToStringList(
|
|
111
|
+
d: [Word, Word | Word[]][],
|
|
112
|
+
indentLevel = 0,
|
|
113
|
+
imports: JSImports,
|
|
114
|
+
indent = " ",
|
|
115
|
+
list = true,
|
|
116
|
+
): string {
|
|
117
|
+
if (d.length === 0) {
|
|
118
|
+
return list ? "[]" : "{}";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let code = "{\n";
|
|
122
|
+
for (const [i, [key, value]] of d.entries()) {
|
|
123
|
+
let valueStr;
|
|
124
|
+
if (Array.isArray(value)) {
|
|
125
|
+
valueStr = "[" + value.map((v) => repr(v, imports)).join(", ") + "]";
|
|
126
|
+
} else {
|
|
127
|
+
valueStr = repr(value, imports);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
code += indent.repeat(indentLevel + 1);
|
|
131
|
+
code += repr(key, imports) + ": " + valueStr;
|
|
132
|
+
code += i < d.length - 1 ? ",\n" : "\n";
|
|
133
|
+
}
|
|
134
|
+
code += indent.repeat(indentLevel) + "}";
|
|
135
|
+
return code;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Backtick quotes are not supported
|
|
139
|
+
const regexEscape = /'|"|\\|\p{C}|[^ \P{Z}]/gu;
|
|
140
|
+
const regexDigit = /[0-9]/;
|
|
141
|
+
export function esc(s: string, quote: "'" | '"' = "'"): string {
|
|
142
|
+
return s.replace(regexEscape, (c: string, index: number, string: string) => {
|
|
143
|
+
switch (c[0]) {
|
|
144
|
+
// https://mathiasbynens.be/notes/javascript-escapes#single
|
|
145
|
+
case "\\":
|
|
146
|
+
return "\\\\";
|
|
147
|
+
case "\b":
|
|
148
|
+
return "\\b";
|
|
149
|
+
case "\f":
|
|
150
|
+
return "\\f";
|
|
151
|
+
case "\n":
|
|
152
|
+
return "\\n";
|
|
153
|
+
case "\r":
|
|
154
|
+
return "\\r";
|
|
155
|
+
case "\t":
|
|
156
|
+
return "\\t";
|
|
157
|
+
case "\v":
|
|
158
|
+
return "\\v";
|
|
159
|
+
case "'":
|
|
160
|
+
case '"':
|
|
161
|
+
return c === quote ? "\\" + c : c;
|
|
162
|
+
case "\0":
|
|
163
|
+
// \0 is null but \01 is an octal escape
|
|
164
|
+
// if we have ['\0', '1', '2']
|
|
165
|
+
// and we converted it to '\\012', it would be interpreted as octal
|
|
166
|
+
// so it needs to be converted to '\\x0012'
|
|
167
|
+
if (!regexDigit.test(string.charAt(index + 1))) {
|
|
168
|
+
return "\\0";
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (c.length === 2) {
|
|
174
|
+
const first = c.charCodeAt(0);
|
|
175
|
+
const second = c.charCodeAt(1);
|
|
176
|
+
return (
|
|
177
|
+
"\\u" +
|
|
178
|
+
first.toString(16).padStart(4, "0") +
|
|
179
|
+
"\\u" +
|
|
180
|
+
second.toString(16).padStart(4, "0")
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const hex = c.charCodeAt(0).toString(16);
|
|
185
|
+
if (hex.length > 2) {
|
|
186
|
+
return "\\u" + hex.padStart(4, "0");
|
|
187
|
+
}
|
|
188
|
+
return "\\x" + hex.padStart(2, "0");
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export function reprStr(s: string, quote?: "'" | '"'): string {
|
|
193
|
+
if (quote === undefined) {
|
|
194
|
+
quote = "'";
|
|
195
|
+
if (s.includes("'") && !s.includes('"')) {
|
|
196
|
+
quote = '"';
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return quote + esc(s, quote) + quote;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type JSImports = [string, string][];
|
|
203
|
+
export function addImport(imports: JSImports, name: string, from: string) {
|
|
204
|
+
// TODO: this is linear
|
|
205
|
+
for (const [n, f] of imports) {
|
|
206
|
+
if (n === name && f === from) return;
|
|
207
|
+
}
|
|
208
|
+
imports.push([name, from]);
|
|
209
|
+
}
|
|
210
|
+
export function reprImports(imports: JSImports): string {
|
|
211
|
+
let ret = "";
|
|
212
|
+
for (const [name, from] of imports.sort(bySecondElem)) {
|
|
213
|
+
if (name.startsWith("* as")) {
|
|
214
|
+
ret += `import ${name} from ${reprStr(from)};\n`;
|
|
215
|
+
} else {
|
|
216
|
+
ret += `import { ${name} } from ${reprStr(from)};\n`;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return ret;
|
|
220
|
+
}
|
|
221
|
+
export function reprImportsRequire(imports: JSImports): string {
|
|
222
|
+
const ret: string[] = [];
|
|
223
|
+
|
|
224
|
+
if (imports.length === 0) {
|
|
225
|
+
return "";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
for (const [name, from] of imports.sort(bySecondElem)) {
|
|
229
|
+
if (name.startsWith("* as ")) {
|
|
230
|
+
ret.push(
|
|
231
|
+
`const ${name.slice("* as ".length)} = require(${reprStr(from)});`,
|
|
232
|
+
);
|
|
233
|
+
} else if (name.includes(".")) {
|
|
234
|
+
ret.push(`const ${name} = require(${reprStr(from)}).${name};`);
|
|
235
|
+
} else {
|
|
236
|
+
ret.push(`const ${name} = require(${reprStr(from)});`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return ret.join("\n") + "\n";
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function repr(w: Word, imports: JSImports): string {
|
|
243
|
+
// Node
|
|
244
|
+
const ret: string[] = [];
|
|
245
|
+
for (const t of w.tokens) {
|
|
246
|
+
if (typeof t === "string") {
|
|
247
|
+
ret.push(reprStr(t));
|
|
248
|
+
} else if (t.type === "variable") {
|
|
249
|
+
ret.push("process.env[" + reprStr(t.value) + "]");
|
|
250
|
+
} else {
|
|
251
|
+
ret.push("execSync(" + reprStr(t.value) + ").stdout");
|
|
252
|
+
addImport(imports, "execSync", "node:child_process");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return ret.join(" + ");
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function reprBrowser(w: Word, warnings: [string, string][]): string {
|
|
259
|
+
const ret: string[] = [];
|
|
260
|
+
for (const t of w.tokens) {
|
|
261
|
+
if (typeof t === "string") {
|
|
262
|
+
ret.push(reprStr(t));
|
|
263
|
+
} else {
|
|
264
|
+
ret.push(reprStr(t.text));
|
|
265
|
+
if (t.type === "variable") {
|
|
266
|
+
warnings.push([
|
|
267
|
+
"browser-has-no-env",
|
|
268
|
+
"Can't access environment variable in browser JS: " +
|
|
269
|
+
JSON.stringify(t.value),
|
|
270
|
+
]);
|
|
271
|
+
} else {
|
|
272
|
+
warnings.push([
|
|
273
|
+
"browser-has-no-shell",
|
|
274
|
+
"Can't run subcommands in browser JS: " + JSON.stringify(t.value),
|
|
275
|
+
]);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return ret.join(" + ");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function reprFetch(
|
|
283
|
+
w: Word,
|
|
284
|
+
isNode: boolean,
|
|
285
|
+
imports: JSImports,
|
|
286
|
+
): string {
|
|
287
|
+
if (!isNode) {
|
|
288
|
+
// TODO: warn
|
|
289
|
+
return reprStr(w.toString());
|
|
290
|
+
}
|
|
291
|
+
return repr(w, imports);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export function asParseFloat(w: Word, imports: JSImports): string {
|
|
295
|
+
if (w.isString()) {
|
|
296
|
+
const originalValue = w.toString();
|
|
297
|
+
// TODO: reimplement curl's float parsing instead of parseFloat()
|
|
298
|
+
const asFloat = parseFloat(originalValue);
|
|
299
|
+
if (!isNaN(asFloat)) {
|
|
300
|
+
return originalValue;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return "parseFloat(" + repr(w, imports) + ")";
|
|
304
|
+
}
|
|
305
|
+
export function asParseFloatTimes1000(w: Word, imports: JSImports): string {
|
|
306
|
+
if (w.isString()) {
|
|
307
|
+
const originalValue = w.toString();
|
|
308
|
+
// TODO: reimplement curl's float parsing instead of parseFloat()
|
|
309
|
+
// TODO: check overflow
|
|
310
|
+
const asFloat = parseFloat(originalValue) * 1000;
|
|
311
|
+
if (!isNaN(asFloat)) {
|
|
312
|
+
return asFloat.toString();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return "parseFloat(" + repr(w, imports) + ") * 1000";
|
|
316
|
+
}
|
|
317
|
+
export function asParseInt(w: Word, imports: JSImports): string {
|
|
318
|
+
if (w.isString()) {
|
|
319
|
+
const originalValue = w.toString();
|
|
320
|
+
// TODO: reimplement curl's int parsing instead of parseInt()
|
|
321
|
+
const asInt = parseInt(originalValue);
|
|
322
|
+
if (!isNaN(asInt)) {
|
|
323
|
+
return originalValue;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return "parseInt(" + repr(w, imports) + ")";
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export function bySecondElem(a: [string, string], b: [string, string]): number {
|
|
330
|
+
return a[1].localeCompare(b[1]);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export function toURLSearchParams(
|
|
334
|
+
query: [QueryList, QueryDict | null | undefined],
|
|
335
|
+
imports: JSImports,
|
|
336
|
+
indent = 1,
|
|
337
|
+
): string {
|
|
338
|
+
const [queryList, queryDict] = query;
|
|
339
|
+
const queryObj =
|
|
340
|
+
queryDict && queryDict.every((q) => !Array.isArray(q[1]))
|
|
341
|
+
? reprAsStringToStringDict(queryDict as [Word, Word][], indent, imports)
|
|
342
|
+
: reprAsStringTuples(queryList, indent, imports);
|
|
343
|
+
return "new URLSearchParams(" + queryObj + ")";
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export function toDictOrURLSearchParams(
|
|
347
|
+
query: [QueryList, QueryDict | null | undefined],
|
|
348
|
+
imports: JSImports,
|
|
349
|
+
indent = 1,
|
|
350
|
+
): string {
|
|
351
|
+
const [queryList, queryDict] = query;
|
|
352
|
+
|
|
353
|
+
if (queryDict && queryDict.every((v) => !Array.isArray(v[1]))) {
|
|
354
|
+
return reprAsStringToStringDict(
|
|
355
|
+
queryDict as [Word, Word][],
|
|
356
|
+
indent,
|
|
357
|
+
imports,
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return (
|
|
362
|
+
"new URLSearchParams(" +
|
|
363
|
+
reprAsStringTuples(queryList, indent, imports) +
|
|
364
|
+
")"
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function toFormData(
|
|
369
|
+
multipartUploads: FormParam[],
|
|
370
|
+
imports: JSImports,
|
|
371
|
+
fetchImports: Set<string>,
|
|
372
|
+
warnings: Warnings,
|
|
373
|
+
isNode = true,
|
|
374
|
+
): string {
|
|
375
|
+
let code = "new FormData();\n";
|
|
376
|
+
for (const m of multipartUploads) {
|
|
377
|
+
// TODO: use .set() if all names are unique?
|
|
378
|
+
code += "form.append(" + reprFetch(m.name, isNode, imports) + ", ";
|
|
379
|
+
if ("contentFile" in m) {
|
|
380
|
+
if (isNode) {
|
|
381
|
+
if (eq(m.contentFile, "-")) {
|
|
382
|
+
addImport(imports, "* as fs", "fs");
|
|
383
|
+
code += "fs.readFileSync(0).toString()";
|
|
384
|
+
if (m.filename) {
|
|
385
|
+
code += ", " + reprFetch(m.filename, isNode, imports);
|
|
386
|
+
}
|
|
387
|
+
} else {
|
|
388
|
+
fetchImports.add("fileFromSync");
|
|
389
|
+
// TODO: do this in a way that doesn't set filename="" if we don't have filename
|
|
390
|
+
code +=
|
|
391
|
+
"fileFromSync(" + reprFetch(m.contentFile, isNode, imports) + ")";
|
|
392
|
+
}
|
|
393
|
+
} else {
|
|
394
|
+
// TODO: does the second argument get sent as filename="" ?
|
|
395
|
+
code +=
|
|
396
|
+
"File(['<data goes here>'], " +
|
|
397
|
+
reprFetch(m.contentFile, isNode, imports) +
|
|
398
|
+
")";
|
|
399
|
+
// TODO: (massive todo) we could read the file if we're running in the command line
|
|
400
|
+
warnings.push([
|
|
401
|
+
"--form",
|
|
402
|
+
"you can't read a file for --form/-F in the browser",
|
|
403
|
+
]);
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
code += reprFetch(m.content, isNode, imports);
|
|
407
|
+
}
|
|
408
|
+
code += ");\n";
|
|
409
|
+
}
|
|
410
|
+
return code;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function getDataString(
|
|
414
|
+
request: Request,
|
|
415
|
+
data: Word,
|
|
416
|
+
isNode: boolean,
|
|
417
|
+
imports: JSImports,
|
|
418
|
+
): [string, string | null] {
|
|
419
|
+
const originalStringRepr = reprFetch(data, isNode, imports);
|
|
420
|
+
|
|
421
|
+
const contentType = request.headers.getContentType();
|
|
422
|
+
if (contentType === "application/json") {
|
|
423
|
+
try {
|
|
424
|
+
const dataStr = data.toString();
|
|
425
|
+
const parsed = JSON.parse(dataStr);
|
|
426
|
+
// Only bother for arrays and {}
|
|
427
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
428
|
+
return [originalStringRepr, null];
|
|
429
|
+
}
|
|
430
|
+
const roundtrips = JSON.stringify(parsed) === dataStr;
|
|
431
|
+
const jsonAsJavaScript = reprObj(parsed, 1);
|
|
432
|
+
|
|
433
|
+
const dataString = "JSON.stringify(" + jsonAsJavaScript + ")";
|
|
434
|
+
return [dataString, roundtrips ? null : originalStringRepr];
|
|
435
|
+
} catch {
|
|
436
|
+
return [originalStringRepr, null];
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
440
|
+
try {
|
|
441
|
+
const [queryList, queryDict] = parseQueryString(data);
|
|
442
|
+
if (queryList) {
|
|
443
|
+
// Technically node-fetch sends
|
|
444
|
+
// application/x-www-form-urlencoded;charset=utf-8
|
|
445
|
+
// TODO: handle repeated content-type header
|
|
446
|
+
if (
|
|
447
|
+
eq(
|
|
448
|
+
request.headers.get("content-type"),
|
|
449
|
+
"application/x-www-form-urlencoded",
|
|
450
|
+
)
|
|
451
|
+
) {
|
|
452
|
+
request.headers.delete("content-type");
|
|
453
|
+
}
|
|
454
|
+
// TODO: check roundtrip, add a comment
|
|
455
|
+
// TODO: this isn't a dict anymore
|
|
456
|
+
return [toURLSearchParams([queryList, queryDict], imports), null];
|
|
457
|
+
}
|
|
458
|
+
return [originalStringRepr, null];
|
|
459
|
+
} catch {
|
|
460
|
+
return [originalStringRepr, null];
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return [originalStringRepr, null];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export function getData(
|
|
467
|
+
request: Request,
|
|
468
|
+
isNode: boolean,
|
|
469
|
+
imports: JSImports,
|
|
470
|
+
): [string, string | null] {
|
|
471
|
+
if (!request.dataArray || request.multipartUploads) {
|
|
472
|
+
return ["", null];
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (
|
|
476
|
+
request.dataArray.length === 1 &&
|
|
477
|
+
request.dataArray[0] instanceof Word &&
|
|
478
|
+
request.dataArray[0].isString()
|
|
479
|
+
) {
|
|
480
|
+
try {
|
|
481
|
+
return getDataString(request, request.dataArray[0], isNode, imports);
|
|
482
|
+
} catch {}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const parts = [];
|
|
486
|
+
const hasBinary = request.dataArray.some(
|
|
487
|
+
(d) => !(d instanceof Word) && d.filetype === "binary",
|
|
488
|
+
);
|
|
489
|
+
const encoding = hasBinary ? "" : ", 'utf-8'";
|
|
490
|
+
for (const d of request.dataArray) {
|
|
491
|
+
if (d instanceof Word) {
|
|
492
|
+
parts.push(repr(d, imports));
|
|
493
|
+
} else {
|
|
494
|
+
const { filetype, name, filename } = d;
|
|
495
|
+
if (filetype === "urlencode" && name) {
|
|
496
|
+
// TODO: add this to the previous Word
|
|
497
|
+
parts.push(reprFetch(name, isNode, imports));
|
|
498
|
+
}
|
|
499
|
+
// TODO: use the filetype
|
|
500
|
+
if (eq(filename, "-")) {
|
|
501
|
+
if (isNode) {
|
|
502
|
+
addImport(imports, "* as fs", "fs");
|
|
503
|
+
parts.push("fs.readFileSync(0" + encoding + ")");
|
|
504
|
+
} else {
|
|
505
|
+
// TODO: something else
|
|
506
|
+
// TODO: warn that file needs content
|
|
507
|
+
parts.push("new File([/* contents */], '<stdin>')");
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
if (isNode) {
|
|
511
|
+
addImport(imports, "* as fs", "fs");
|
|
512
|
+
parts.push(
|
|
513
|
+
"fs.readFileSync(" +
|
|
514
|
+
reprFetch(filename, isNode, imports) +
|
|
515
|
+
encoding +
|
|
516
|
+
")",
|
|
517
|
+
);
|
|
518
|
+
} else {
|
|
519
|
+
// TODO: warn that file needs content
|
|
520
|
+
parts.push(
|
|
521
|
+
"new File([/* contents */], " +
|
|
522
|
+
reprFetch(filename, isNode, imports) +
|
|
523
|
+
")",
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (parts.length === 0) {
|
|
531
|
+
return ["''", null];
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (parts.length === 1) {
|
|
535
|
+
return [parts[0], null];
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
let [start, joiner, end] = ["new ArrayBuffer(", ", ", ")"];
|
|
539
|
+
const totalLength = parts.reduce((a, b) => a + b.length, 0);
|
|
540
|
+
if (totalLength > 80) {
|
|
541
|
+
start += "\n ";
|
|
542
|
+
joiner = ",\n ";
|
|
543
|
+
end = "\n )";
|
|
544
|
+
}
|
|
545
|
+
return [start + parts.join(joiner) + end, null];
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function requestToJavaScriptOrNode(
|
|
549
|
+
request: Request,
|
|
550
|
+
warnings: Warnings,
|
|
551
|
+
fetchImports: Set<string>,
|
|
552
|
+
imports: JSImports,
|
|
553
|
+
isNode: boolean,
|
|
554
|
+
): string {
|
|
555
|
+
warnIfPartsIgnored(request, warnings, {
|
|
556
|
+
multipleUrls: true,
|
|
557
|
+
dataReadsFile: true,
|
|
558
|
+
// Not actually supported, just warned per-URL
|
|
559
|
+
queryReadsFile: true,
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
let code = "";
|
|
563
|
+
|
|
564
|
+
if (request.multipartUploads) {
|
|
565
|
+
if (isNode) {
|
|
566
|
+
// TODO: remove once Node 16 is EOL'd on 2023-09-11
|
|
567
|
+
fetchImports.add("FormData");
|
|
568
|
+
}
|
|
569
|
+
code +=
|
|
570
|
+
"const form = " +
|
|
571
|
+
toFormData(
|
|
572
|
+
request.multipartUploads,
|
|
573
|
+
imports,
|
|
574
|
+
fetchImports,
|
|
575
|
+
warnings,
|
|
576
|
+
isNode,
|
|
577
|
+
);
|
|
578
|
+
code += "\n";
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Can delete content-type header
|
|
582
|
+
const [dataString, commentedOutDataString] = getData(
|
|
583
|
+
request,
|
|
584
|
+
isNode,
|
|
585
|
+
imports,
|
|
586
|
+
);
|
|
587
|
+
|
|
588
|
+
let fn = "fetch";
|
|
589
|
+
if (request.urls[0].auth && request.authType === "digest") {
|
|
590
|
+
// TODO: if 'Authorization:' header is specified, don't set this
|
|
591
|
+
const [user, password] = request.urls[0].auth;
|
|
592
|
+
addImport(imports, "* as DigestFetch", "digest-fetch");
|
|
593
|
+
code +=
|
|
594
|
+
"const client = new DigestFetch(" +
|
|
595
|
+
reprFetch(user, isNode, imports) +
|
|
596
|
+
", " +
|
|
597
|
+
reprFetch(password, isNode, imports) +
|
|
598
|
+
");\n";
|
|
599
|
+
fn = "client.fetch";
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
for (const urlObj of request.urls) {
|
|
603
|
+
code += fn + "(" + reprFetch(urlObj.url, isNode, imports);
|
|
604
|
+
if (urlObj.queryReadsFile) {
|
|
605
|
+
warnings.push([
|
|
606
|
+
"unsafe-query",
|
|
607
|
+
// TODO: better wording
|
|
608
|
+
"the URL query string is not correct, " +
|
|
609
|
+
JSON.stringify("@" + urlObj.queryReadsFile) +
|
|
610
|
+
" means it should read the file " +
|
|
611
|
+
JSON.stringify(urlObj.queryReadsFile),
|
|
612
|
+
]);
|
|
613
|
+
}
|
|
614
|
+
const method = urlObj.method.toLowerCase();
|
|
615
|
+
const methodStr = urlObj.method.toString();
|
|
616
|
+
if (method.isString() && FORBIDDEN_METHODS.includes(methodStr)) {
|
|
617
|
+
warnings.push([
|
|
618
|
+
"forbidden-method",
|
|
619
|
+
"the method " +
|
|
620
|
+
JSON.stringify(methodStr) +
|
|
621
|
+
" is not allowed in fetch()",
|
|
622
|
+
]);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
let optionsCode = "";
|
|
626
|
+
if (!eq(method, "get")) {
|
|
627
|
+
// TODO: If you pass a weird method to fetch() it won't uppercase it
|
|
628
|
+
// const methods = []
|
|
629
|
+
// const method = methods.includes(request.method.toLowerCase()) ? request.method.toUpperCase() : request.method
|
|
630
|
+
optionsCode +=
|
|
631
|
+
" method: " + reprFetch(urlObj.method, isNode, imports) + ",\n";
|
|
632
|
+
}
|
|
633
|
+
if (
|
|
634
|
+
request.headers.length ||
|
|
635
|
+
(urlObj.auth && request.authType === "basic")
|
|
636
|
+
) {
|
|
637
|
+
optionsCode += " headers: {\n";
|
|
638
|
+
for (const [headerName, headerValue] of request.headers) {
|
|
639
|
+
optionsCode +=
|
|
640
|
+
" " +
|
|
641
|
+
reprFetch(headerName, isNode, imports) +
|
|
642
|
+
": " +
|
|
643
|
+
reprFetch(headerValue || new Word(), isNode, imports) +
|
|
644
|
+
",\n";
|
|
645
|
+
if (
|
|
646
|
+
!isNode &&
|
|
647
|
+
headerName.isString() &&
|
|
648
|
+
FORBIDDEN_HEADERS.includes(headerName.toString().toLowerCase())
|
|
649
|
+
) {
|
|
650
|
+
warnings.push([
|
|
651
|
+
"forbidden-header",
|
|
652
|
+
JSON.stringify(headerName.toString()) +
|
|
653
|
+
" header is forbidden in fetch()",
|
|
654
|
+
]);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (urlObj.auth && request.authType === "basic") {
|
|
658
|
+
// TODO: if -H 'Authorization:' is passed, don't set this
|
|
659
|
+
optionsCode +=
|
|
660
|
+
" 'Authorization': 'Basic ' + btoa(" +
|
|
661
|
+
reprFetch(joinWords(urlObj.auth, ":"), isNode, imports) +
|
|
662
|
+
"),\n";
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (optionsCode.endsWith(",\n")) {
|
|
666
|
+
optionsCode = optionsCode.slice(0, -2);
|
|
667
|
+
optionsCode += "\n";
|
|
668
|
+
}
|
|
669
|
+
optionsCode += " },\n";
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
if (urlObj.uploadFile) {
|
|
673
|
+
if (isNode) {
|
|
674
|
+
fetchImports.add("fileFromSync");
|
|
675
|
+
optionsCode +=
|
|
676
|
+
" body: fileFromSync(" +
|
|
677
|
+
reprFetch(urlObj.uploadFile, isNode, imports) +
|
|
678
|
+
"),\n";
|
|
679
|
+
} else {
|
|
680
|
+
optionsCode +=
|
|
681
|
+
" body: File(['<data goes here>'], " +
|
|
682
|
+
reprFetch(urlObj.uploadFile, isNode, imports) +
|
|
683
|
+
"),\n";
|
|
684
|
+
warnings.push([
|
|
685
|
+
"--form",
|
|
686
|
+
"you can't read a file for --upload-file/-F in the browser",
|
|
687
|
+
]);
|
|
688
|
+
}
|
|
689
|
+
} else if (request.multipartUploads) {
|
|
690
|
+
optionsCode += " body: form,\n";
|
|
691
|
+
} else if (request.data) {
|
|
692
|
+
if (commentedOutDataString) {
|
|
693
|
+
optionsCode += " // body: " + commentedOutDataString + ",\n";
|
|
694
|
+
}
|
|
695
|
+
optionsCode += " body: " + dataString + ",\n";
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (isNode && request.proxy) {
|
|
699
|
+
// TODO: do this parsing in utils.ts
|
|
700
|
+
const proxy = request.proxy.includes("://")
|
|
701
|
+
? request.proxy
|
|
702
|
+
: request.proxy.prepend("http://");
|
|
703
|
+
// TODO: could be more accurate
|
|
704
|
+
let [protocol] = proxy.split("://", 2);
|
|
705
|
+
protocol = protocol.toLowerCase();
|
|
706
|
+
|
|
707
|
+
if (!protocol.toBool()) {
|
|
708
|
+
protocol = new Word("http");
|
|
709
|
+
}
|
|
710
|
+
if (eq(protocol, "socks")) {
|
|
711
|
+
protocol = new Word("socks4");
|
|
712
|
+
proxy.replace(/^socks/, "socks4");
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (
|
|
716
|
+
eq(protocol, "socks4") ||
|
|
717
|
+
eq(protocol, "socks5") ||
|
|
718
|
+
eq(protocol, "socks5h") ||
|
|
719
|
+
eq(protocol, "socks4a")
|
|
720
|
+
) {
|
|
721
|
+
addImport(imports, "{ SocksProxyAgent }", "socks-proxy-agent");
|
|
722
|
+
optionsCode +=
|
|
723
|
+
" agent: new SocksProxyAgent(" +
|
|
724
|
+
reprFetch(proxy, isNode, imports) +
|
|
725
|
+
"),\n";
|
|
726
|
+
} else if (eq(protocol, "http") || eq(protocol, "https")) {
|
|
727
|
+
addImport(imports, "HttpsProxyAgent", "https-proxy-agent");
|
|
728
|
+
optionsCode +=
|
|
729
|
+
" agent: new HttpsProxyAgent(" +
|
|
730
|
+
reprFetch(proxy, isNode, imports) +
|
|
731
|
+
"),\n";
|
|
732
|
+
} else {
|
|
733
|
+
warnings.push([
|
|
734
|
+
"--proxy",
|
|
735
|
+
"failed to parse --proxy/-x or unknown protocol: " + protocol,
|
|
736
|
+
]);
|
|
737
|
+
// or this?
|
|
738
|
+
// throw new CCError('Unsupported proxy scheme for ' + reprFetch(request.proxy))
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
if (optionsCode) {
|
|
743
|
+
if (optionsCode.endsWith(",\n")) {
|
|
744
|
+
optionsCode = optionsCode.slice(0, -2);
|
|
745
|
+
}
|
|
746
|
+
code += ", {\n";
|
|
747
|
+
code += optionsCode;
|
|
748
|
+
code += "\n}";
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
code += ");\n";
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// TODO: generate some code for the output, like .json() if 'Accept': 'application/json'
|
|
755
|
+
|
|
756
|
+
return code;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
export function _toJavaScriptOrNode(
|
|
760
|
+
requests: Request[],
|
|
761
|
+
warnings: Warnings,
|
|
762
|
+
isNode: boolean,
|
|
763
|
+
): string {
|
|
764
|
+
const fetchImports = new Set<string>();
|
|
765
|
+
const imports: JSImports = [];
|
|
766
|
+
|
|
767
|
+
const code = requests
|
|
768
|
+
.map((r) =>
|
|
769
|
+
requestToJavaScriptOrNode(r, warnings, fetchImports, imports, isNode),
|
|
770
|
+
)
|
|
771
|
+
.join("\n");
|
|
772
|
+
|
|
773
|
+
let importCode = "";
|
|
774
|
+
if (isNode) {
|
|
775
|
+
importCode += "import fetch";
|
|
776
|
+
if (fetchImports.size) {
|
|
777
|
+
importCode += ", { " + Array.from(fetchImports).sort().join(", ") + " }";
|
|
778
|
+
}
|
|
779
|
+
importCode += " from 'node-fetch';\n";
|
|
780
|
+
}
|
|
781
|
+
if (imports.length) {
|
|
782
|
+
for (const [varName, imp] of Array.from(imports).sort(bySecondElem)) {
|
|
783
|
+
// TODO: check this
|
|
784
|
+
importCode += "import " + varName + " from " + reprStr(imp) + ";\n";
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
if (importCode) {
|
|
789
|
+
return importCode + "\n" + code;
|
|
790
|
+
}
|
|
791
|
+
return code;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
export function _toJavaScript(
|
|
795
|
+
requests: Request[],
|
|
796
|
+
warnings: Warnings = [],
|
|
797
|
+
): string {
|
|
798
|
+
return _toJavaScriptOrNode(requests, warnings, false);
|
|
799
|
+
}
|
|
800
|
+
export function _toNode(requests: Request[], warnings: Warnings = []): string {
|
|
801
|
+
return _toJavaScriptOrNode(requests, warnings, true);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
export function toJavaScriptWarn(
|
|
805
|
+
curlCommand: string | string[],
|
|
806
|
+
warnings: Warnings = [],
|
|
807
|
+
): [string, Warnings] {
|
|
808
|
+
const requests = parse(curlCommand, javaScriptSupportedArgs, warnings);
|
|
809
|
+
return [_toJavaScript(requests, warnings), warnings];
|
|
810
|
+
}
|
|
811
|
+
export function toJavaScript(curlCommand: string | string[]): string {
|
|
812
|
+
const [result] = toJavaScriptWarn(curlCommand);
|
|
813
|
+
return result;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
export function toNodeWarn(
|
|
817
|
+
curlCommand: string | string[],
|
|
818
|
+
warnings: Warnings = [],
|
|
819
|
+
): [string, Warnings] {
|
|
820
|
+
const requests = parse(curlCommand, nodeSupportedArgs, warnings);
|
|
821
|
+
return [_toNode(requests, warnings), warnings];
|
|
822
|
+
}
|
|
823
|
+
export function toNode(curlCommand: string | string[]): string {
|
|
824
|
+
return toNodeWarn(curlCommand)[0];
|
|
825
|
+
}
|