@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.
Files changed (270) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -0
  3. package/dist/src/Headers.d.ts +23 -0
  4. package/dist/src/Headers.js +287 -0
  5. package/dist/src/Headers.js.map +1 -0
  6. package/dist/src/Query.d.ts +8 -0
  7. package/dist/src/Query.js +136 -0
  8. package/dist/src/Query.js.map +1 -0
  9. package/dist/src/Request.d.ts +200 -0
  10. package/dist/src/Request.js +1191 -0
  11. package/dist/src/Request.js.map +1 -0
  12. package/dist/src/Warnings.d.ts +15 -0
  13. package/dist/src/Warnings.js +111 -0
  14. package/dist/src/Warnings.js.map +1 -0
  15. package/dist/src/cli.d.ts +2 -0
  16. package/dist/src/cli.js +333 -0
  17. package/dist/src/cli.js.map +1 -0
  18. package/dist/src/curl/auth.d.ts +12 -0
  19. package/dist/src/curl/auth.js +40 -0
  20. package/dist/src/curl/auth.js.map +1 -0
  21. package/dist/src/curl/form.d.ts +28 -0
  22. package/dist/src/curl/form.js +218 -0
  23. package/dist/src/curl/form.js.map +1 -0
  24. package/dist/src/curl/opts.d.ts +2052 -0
  25. package/dist/src/curl/opts.js +1000 -0
  26. package/dist/src/curl/opts.js.map +1 -0
  27. package/dist/src/curl/url.d.ts +14 -0
  28. package/dist/src/curl/url.js +218 -0
  29. package/dist/src/curl/url.js.map +1 -0
  30. package/dist/src/generators/ansible.d.ts +5 -0
  31. package/dist/src/generators/ansible.js +282 -0
  32. package/dist/src/generators/ansible.js.map +1 -0
  33. package/dist/src/generators/c.d.ts +12 -0
  34. package/dist/src/generators/c.js +1230 -0
  35. package/dist/src/generators/c.js.map +1 -0
  36. package/dist/src/generators/cfml.d.ts +5 -0
  37. package/dist/src/generators/cfml.js +134 -0
  38. package/dist/src/generators/cfml.js.map +1 -0
  39. package/dist/src/generators/clojure.d.ts +7 -0
  40. package/dist/src/generators/clojure.js +436 -0
  41. package/dist/src/generators/clojure.js.map +1 -0
  42. package/dist/src/generators/csharp.d.ts +8 -0
  43. package/dist/src/generators/csharp.js +356 -0
  44. package/dist/src/generators/csharp.js.map +1 -0
  45. package/dist/src/generators/dart.d.ts +5 -0
  46. package/dist/src/generators/dart.js +273 -0
  47. package/dist/src/generators/dart.js.map +1 -0
  48. package/dist/src/generators/elixir.d.ts +8 -0
  49. package/dist/src/generators/elixir.js +296 -0
  50. package/dist/src/generators/elixir.js.map +1 -0
  51. package/dist/src/generators/go.d.ts +5 -0
  52. package/dist/src/generators/go.js +228 -0
  53. package/dist/src/generators/go.js.map +1 -0
  54. package/dist/src/generators/har.d.ts +7 -0
  55. package/dist/src/generators/har.js +115 -0
  56. package/dist/src/generators/har.js.map +1 -0
  57. package/dist/src/generators/http.d.ts +7 -0
  58. package/dist/src/generators/http.js +165 -0
  59. package/dist/src/generators/http.js.map +1 -0
  60. package/dist/src/generators/httpie.d.ts +5 -0
  61. package/dist/src/generators/httpie.js +446 -0
  62. package/dist/src/generators/httpie.js.map +1 -0
  63. package/dist/src/generators/java/httpurlconnection.d.ts +5 -0
  64. package/dist/src/generators/java/httpurlconnection.js +123 -0
  65. package/dist/src/generators/java/httpurlconnection.js.map +1 -0
  66. package/dist/src/generators/java/java.d.ts +8 -0
  67. package/dist/src/generators/java/java.js +247 -0
  68. package/dist/src/generators/java/java.js.map +1 -0
  69. package/dist/src/generators/java/jsoup.d.ts +5 -0
  70. package/dist/src/generators/java/jsoup.js +152 -0
  71. package/dist/src/generators/java/jsoup.js.map +1 -0
  72. package/dist/src/generators/java/okhttp.d.ts +5 -0
  73. package/dist/src/generators/java/okhttp.js +232 -0
  74. package/dist/src/generators/java/okhttp.js.map +1 -0
  75. package/dist/src/generators/javascript/axios.d.ts +5 -0
  76. package/dist/src/generators/javascript/axios.js +332 -0
  77. package/dist/src/generators/javascript/axios.js.map +1 -0
  78. package/dist/src/generators/javascript/got.d.ts +5 -0
  79. package/dist/src/generators/javascript/got.js +277 -0
  80. package/dist/src/generators/javascript/got.js.map +1 -0
  81. package/dist/src/generators/javascript/http.d.ts +8 -0
  82. package/dist/src/generators/javascript/http.js +183 -0
  83. package/dist/src/generators/javascript/http.js.map +1 -0
  84. package/dist/src/generators/javascript/javascript.d.ts +37 -0
  85. package/dist/src/generators/javascript/javascript.js +676 -0
  86. package/dist/src/generators/javascript/javascript.js.map +1 -0
  87. package/dist/src/generators/javascript/jquery.d.ts +15 -0
  88. package/dist/src/generators/javascript/jquery.js +297 -0
  89. package/dist/src/generators/javascript/jquery.js.map +1 -0
  90. package/dist/src/generators/javascript/ky.d.ts +7 -0
  91. package/dist/src/generators/javascript/ky.js +245 -0
  92. package/dist/src/generators/javascript/ky.js.map +1 -0
  93. package/dist/src/generators/javascript/request.d.ts +5 -0
  94. package/dist/src/generators/javascript/request.js +113 -0
  95. package/dist/src/generators/javascript/request.js.map +1 -0
  96. package/dist/src/generators/javascript/superagent.d.ts +10 -0
  97. package/dist/src/generators/javascript/superagent.js +301 -0
  98. package/dist/src/generators/javascript/superagent.js.map +1 -0
  99. package/dist/src/generators/javascript/xhr.d.ts +8 -0
  100. package/dist/src/generators/javascript/xhr.js +147 -0
  101. package/dist/src/generators/javascript/xhr.js.map +1 -0
  102. package/dist/src/generators/json.d.ts +45 -0
  103. package/dist/src/generators/json.js +197 -0
  104. package/dist/src/generators/json.js.map +1 -0
  105. package/dist/src/generators/julia.d.ts +8 -0
  106. package/dist/src/generators/julia.js +365 -0
  107. package/dist/src/generators/julia.js.map +1 -0
  108. package/dist/src/generators/kotlin.d.ts +8 -0
  109. package/dist/src/generators/kotlin.js +325 -0
  110. package/dist/src/generators/kotlin.js.map +1 -0
  111. package/dist/src/generators/lua.d.ts +5 -0
  112. package/dist/src/generators/lua.js +192 -0
  113. package/dist/src/generators/lua.js.map +1 -0
  114. package/dist/src/generators/matlab/common.d.ts +16 -0
  115. package/dist/src/generators/matlab/common.js +238 -0
  116. package/dist/src/generators/matlab/common.js.map +1 -0
  117. package/dist/src/generators/matlab/httpinterface.d.ts +2 -0
  118. package/dist/src/generators/matlab/httpinterface.js +211 -0
  119. package/dist/src/generators/matlab/httpinterface.js.map +1 -0
  120. package/dist/src/generators/matlab/matlab.d.ts +5 -0
  121. package/dist/src/generators/matlab/matlab.js +29 -0
  122. package/dist/src/generators/matlab/matlab.js.map +1 -0
  123. package/dist/src/generators/matlab/webservices.d.ts +2 -0
  124. package/dist/src/generators/matlab/webservices.js +191 -0
  125. package/dist/src/generators/matlab/webservices.js.map +1 -0
  126. package/dist/src/generators/objectivec.d.ts +8 -0
  127. package/dist/src/generators/objectivec.js +269 -0
  128. package/dist/src/generators/objectivec.js.map +1 -0
  129. package/dist/src/generators/ocaml.d.ts +8 -0
  130. package/dist/src/generators/ocaml.js +150 -0
  131. package/dist/src/generators/ocaml.js.map +1 -0
  132. package/dist/src/generators/perl.d.ts +9 -0
  133. package/dist/src/generators/perl.js +209 -0
  134. package/dist/src/generators/perl.js.map +1 -0
  135. package/dist/src/generators/php/guzzle.d.ts +5 -0
  136. package/dist/src/generators/php/guzzle.js +328 -0
  137. package/dist/src/generators/php/guzzle.js.map +1 -0
  138. package/dist/src/generators/php/php.d.ts +8 -0
  139. package/dist/src/generators/php/php.js +217 -0
  140. package/dist/src/generators/php/php.js.map +1 -0
  141. package/dist/src/generators/php/requests.d.ts +5 -0
  142. package/dist/src/generators/php/requests.js +89 -0
  143. package/dist/src/generators/php/requests.js.map +1 -0
  144. package/dist/src/generators/powershell.d.ts +11 -0
  145. package/dist/src/generators/powershell.js +377 -0
  146. package/dist/src/generators/powershell.js.map +1 -0
  147. package/dist/src/generators/python/http.d.ts +5 -0
  148. package/dist/src/generators/python/http.js +128 -0
  149. package/dist/src/generators/python/http.js.map +1 -0
  150. package/dist/src/generators/python/python.d.ts +22 -0
  151. package/dist/src/generators/python/python.js +1693 -0
  152. package/dist/src/generators/python/python.js.map +1 -0
  153. package/dist/src/generators/r/httr.d.ts +10 -0
  154. package/dist/src/generators/r/httr.js +298 -0
  155. package/dist/src/generators/r/httr.js.map +1 -0
  156. package/dist/src/generators/r/httr2.d.ts +5 -0
  157. package/dist/src/generators/r/httr2.js +214 -0
  158. package/dist/src/generators/r/httr2.js.map +1 -0
  159. package/dist/src/generators/ruby/httparty.d.ts +6 -0
  160. package/dist/src/generators/ruby/httparty.js +308 -0
  161. package/dist/src/generators/ruby/httparty.js.map +1 -0
  162. package/dist/src/generators/ruby/ruby.d.ts +14 -0
  163. package/dist/src/generators/ruby/ruby.js +515 -0
  164. package/dist/src/generators/ruby/ruby.js.map +1 -0
  165. package/dist/src/generators/rust.d.ts +8 -0
  166. package/dist/src/generators/rust.js +177 -0
  167. package/dist/src/generators/rust.js.map +1 -0
  168. package/dist/src/generators/swift.d.ts +8 -0
  169. package/dist/src/generators/swift.js +219 -0
  170. package/dist/src/generators/swift.js.map +1 -0
  171. package/dist/src/generators/wget.d.ts +8 -0
  172. package/dist/src/generators/wget.js +472 -0
  173. package/dist/src/generators/wget.js.map +1 -0
  174. package/dist/src/index.d.ts +53 -0
  175. package/dist/src/index.js +54 -0
  176. package/dist/src/index.js.map +1 -0
  177. package/dist/src/parse.d.ts +13 -0
  178. package/dist/src/parse.js +43 -0
  179. package/dist/src/parse.js.map +1 -0
  180. package/dist/src/shell/Parser.d.ts +4 -0
  181. package/dist/src/shell/Parser.js +6 -0
  182. package/dist/src/shell/Parser.js.map +1 -0
  183. package/dist/src/shell/Word.d.ts +48 -0
  184. package/dist/src/shell/Word.js +486 -0
  185. package/dist/src/shell/Word.js.map +1 -0
  186. package/dist/src/shell/tokenizer.d.ts +3 -0
  187. package/dist/src/shell/tokenizer.js +610 -0
  188. package/dist/src/shell/tokenizer.js.map +1 -0
  189. package/dist/src/shell/webParser.d.ts +4 -0
  190. package/dist/src/shell/webParser.js +15 -0
  191. package/dist/src/shell/webParser.js.map +1 -0
  192. package/dist/src/utils.d.ts +6 -0
  193. package/dist/src/utils.js +21 -0
  194. package/dist/src/utils.js.map +1 -0
  195. package/dist/tools/compare-requests.d.ts +2 -0
  196. package/dist/tools/compare-requests.js +448 -0
  197. package/dist/tools/compare-requests.js.map +1 -0
  198. package/dist/tools/gen-test.d.ts +2 -0
  199. package/dist/tools/gen-test.js +114 -0
  200. package/dist/tools/gen-test.js.map +1 -0
  201. package/dist/tree-sitter-bash.wasm +0 -0
  202. package/index.d.ts +3 -0
  203. package/package.json +97 -0
  204. package/src/Headers.ts +334 -0
  205. package/src/Query.ts +147 -0
  206. package/src/Request.ts +1649 -0
  207. package/src/Warnings.ts +154 -0
  208. package/src/cli.ts +561 -0
  209. package/src/curl/auth.ts +45 -0
  210. package/src/curl/form.ts +297 -0
  211. package/src/curl/opts.ts +1417 -0
  212. package/src/curl/url.ts +241 -0
  213. package/src/generators/ansible.ts +364 -0
  214. package/src/generators/c.ts +1371 -0
  215. package/src/generators/cfml.ts +155 -0
  216. package/src/generators/clojure.ts +521 -0
  217. package/src/generators/csharp.ts +383 -0
  218. package/src/generators/dart.ts +293 -0
  219. package/src/generators/elixir.ts +349 -0
  220. package/src/generators/go.ts +269 -0
  221. package/src/generators/har.ts +147 -0
  222. package/src/generators/http.ts +194 -0
  223. package/src/generators/httpie.ts +506 -0
  224. package/src/generators/java/httpurlconnection.ts +151 -0
  225. package/src/generators/java/java.ts +280 -0
  226. package/src/generators/java/jsoup.ts +172 -0
  227. package/src/generators/java/okhttp.ts +257 -0
  228. package/src/generators/javascript/axios.ts +395 -0
  229. package/src/generators/javascript/got.ts +362 -0
  230. package/src/generators/javascript/http.ts +232 -0
  231. package/src/generators/javascript/javascript.ts +825 -0
  232. package/src/generators/javascript/jquery.ts +360 -0
  233. package/src/generators/javascript/ky.ts +315 -0
  234. package/src/generators/javascript/request.ts +152 -0
  235. package/src/generators/javascript/superagent.ts +373 -0
  236. package/src/generators/javascript/xhr.ts +192 -0
  237. package/src/generators/json.ts +293 -0
  238. package/src/generators/julia.ts +398 -0
  239. package/src/generators/kotlin.ts +355 -0
  240. package/src/generators/lua.ts +209 -0
  241. package/src/generators/matlab/common.ts +281 -0
  242. package/src/generators/matlab/httpinterface.ts +284 -0
  243. package/src/generators/matlab/matlab.ts +39 -0
  244. package/src/generators/matlab/webservices.ts +263 -0
  245. package/src/generators/objectivec.ts +297 -0
  246. package/src/generators/ocaml.ts +168 -0
  247. package/src/generators/perl.ts +237 -0
  248. package/src/generators/php/guzzle.ts +368 -0
  249. package/src/generators/php/php.ts +239 -0
  250. package/src/generators/php/requests.ts +103 -0
  251. package/src/generators/powershell.ts +430 -0
  252. package/src/generators/python/http.ts +167 -0
  253. package/src/generators/python/python.ts +1934 -0
  254. package/src/generators/r/httr.ts +328 -0
  255. package/src/generators/r/httr2.ts +268 -0
  256. package/src/generators/ruby/httparty.ts +351 -0
  257. package/src/generators/ruby/ruby.ts +564 -0
  258. package/src/generators/rust.ts +243 -0
  259. package/src/generators/swift.ts +235 -0
  260. package/src/generators/wget.ts +533 -0
  261. package/src/index.ts +89 -0
  262. package/src/parse.ts +72 -0
  263. package/src/shell/Parser.ts +8 -0
  264. package/src/shell/Word.ts +531 -0
  265. package/src/shell/tokenizer.ts +736 -0
  266. package/src/shell/webParser.ts +18 -0
  267. package/src/utils.ts +25 -0
  268. package/tools/compare-requests.ts +571 -0
  269. package/tools/extract_curl_args.py +511 -0
  270. package/tools/gen-test.ts +129 -0
@@ -0,0 +1,360 @@
1
+ import { Word, eq } from "../../shell/Word.js";
2
+ import { parse, getFirst, COMMON_SUPPORTED_ARGS } from "../../parse.js";
3
+ import type { Request, Warnings } from "../../parse.js";
4
+ import { parseQueryString } from "../../Query.js";
5
+ import type { Query } from "../../Query.js";
6
+ import type { FormParam } from "../../curl/form.js";
7
+
8
+ import {
9
+ repr,
10
+ reprObj,
11
+ asParseFloatTimes1000,
12
+ type JSImports,
13
+ addImport,
14
+ reprImports,
15
+ } from "./javascript.js";
16
+
17
+ export const supportedArgs = new Set([
18
+ ...COMMON_SUPPORTED_ARGS,
19
+ "form",
20
+ "form-string",
21
+ "max-time",
22
+ ]);
23
+
24
+ export function dedent(s: string): string {
25
+ return s.replace(/^ {2}/gm, "");
26
+ }
27
+ export function indent(s: string, indent = 1): string {
28
+ const indentation = " ".repeat(indent);
29
+ return s.split("\n").join("\n" + indentation);
30
+ }
31
+ export function commentOut(s: string, indent = 0): string {
32
+ const indentation = " ".repeat(indent);
33
+ return s.split("\n").join("\n" + indentation + "// ");
34
+ }
35
+
36
+ export function serializeQuery(
37
+ query: Query,
38
+ imports: JSImports,
39
+ ): [string, boolean] {
40
+ const [queryList, queryDict] = query;
41
+ let code = "";
42
+ let traditional = false;
43
+ if (queryDict) {
44
+ code += "{\n";
45
+ for (const [key, value] of queryDict) {
46
+ code += " " + repr(key, imports) + ": ";
47
+ if (Array.isArray(value)) {
48
+ code += "[" + value.map((v) => repr(v, imports)).join(", ") + "]";
49
+ traditional = true;
50
+ } else {
51
+ code += repr(value, imports);
52
+ }
53
+ code += ",\n";
54
+ }
55
+
56
+ if (code.endsWith(",\n")) {
57
+ code = code.slice(0, -2);
58
+ }
59
+ code += "\n}";
60
+ } else if (queryList) {
61
+ code += "[\n";
62
+ for (const [key, value] of queryList) {
63
+ code +=
64
+ " { name: " +
65
+ repr(key, imports) +
66
+ ", value: " +
67
+ repr(value, imports) +
68
+ " },\n";
69
+ }
70
+ if (code.endsWith(",\n")) {
71
+ code = code.slice(0, -2);
72
+ }
73
+ code += "\n]";
74
+ } else {
75
+ // shouldn't happen
76
+ return ["null", false];
77
+ }
78
+ return [code, traditional];
79
+ }
80
+
81
+ // TODO: @
82
+ function _getDataString(
83
+ data: Word,
84
+ contentType: string | null | undefined,
85
+ exactContentType: Word | null | undefined,
86
+ imports: JSImports,
87
+ ): [Word | null | undefined, string, string | null, boolean] {
88
+ let traditional = false;
89
+ const originalStringRepr = repr(data, imports);
90
+
91
+ if (contentType === "application/json" && data.isString()) {
92
+ const dataStr = data.toString();
93
+ const parsed = JSON.parse(dataStr);
94
+ // Only convert arrays and {} to JavaScript objects
95
+ if (typeof parsed !== "object" || parsed === null) {
96
+ return [exactContentType, originalStringRepr, null, traditional];
97
+ }
98
+ const roundtrips = JSON.stringify(parsed) === dataStr;
99
+ const jsonAsJavaScript = "JSON.stringify(" + reprObj(parsed, 1) + ")";
100
+ return [
101
+ exactContentType,
102
+ jsonAsJavaScript,
103
+ roundtrips ? null : originalStringRepr,
104
+ traditional,
105
+ ];
106
+ }
107
+ if (contentType === "application/x-www-form-urlencoded") {
108
+ const [queryList, queryDict] = parseQueryString(data);
109
+ if (queryList) {
110
+ if (
111
+ eq(exactContentType, "application/x-www-form-urlencoded; charset=utf-8")
112
+ ) {
113
+ exactContentType = null;
114
+ }
115
+
116
+ let queryObj;
117
+ [queryObj, traditional] = serializeQuery([queryList, queryDict], imports);
118
+ // TODO: check roundtrip, add a comment
119
+ return [exactContentType, indent(queryObj), null, traditional];
120
+ }
121
+ }
122
+ return [exactContentType, originalStringRepr, null, traditional];
123
+ }
124
+
125
+ export function getDataString(
126
+ data: Word,
127
+ contentType: string | null | undefined,
128
+ exactContentType: Word | null | undefined,
129
+ imports: JSImports,
130
+ ): [Word | null | undefined, string, string | null, boolean] {
131
+ let dataString: string | null = null;
132
+ let commentedOutDataString: string | null = null;
133
+ let traditional = false;
134
+ try {
135
+ [exactContentType, dataString, commentedOutDataString, traditional] =
136
+ _getDataString(data, contentType, exactContentType, imports);
137
+ } catch {}
138
+ if (!dataString) {
139
+ dataString = repr(data, imports);
140
+ }
141
+ return [exactContentType, dataString, commentedOutDataString, traditional];
142
+ }
143
+
144
+ export function getFormString(
145
+ multipartUploads: FormParam[],
146
+ imports: JSImports,
147
+ ): string {
148
+ let code = "const form = new FormData();\n";
149
+ for (const m of multipartUploads) {
150
+ code += "form.append(" + repr(m.name, imports) + ", ";
151
+ if ("contentFile" in m) {
152
+ // TODO: no fs in browser
153
+ addImport(imports, "* as fs", "fs");
154
+ if (eq(m.contentFile, "-")) {
155
+ code += "fs.readFileSync(0).toString()";
156
+ } else {
157
+ code += "fs.readFileSync(" + repr(m.contentFile, imports) + ")";
158
+ }
159
+ if ("filename" in m && m.filename) {
160
+ code += ", " + repr(m.filename, imports);
161
+ }
162
+ } else {
163
+ code += repr(m.content, imports);
164
+ }
165
+ code += ");\n";
166
+ }
167
+ code += "\n";
168
+ return code;
169
+ }
170
+
171
+ export function _toJavaScriptJquery(
172
+ requests: Request[],
173
+ warnings: Warnings = [],
174
+ ): string {
175
+ const request = getFirst(requests, warnings);
176
+ const imports: JSImports = [];
177
+
178
+ let code = "";
179
+
180
+ // data: passed with these methods will be added to the URL instead
181
+ const nonDataMethods = ["GET", "HEAD"];
182
+ const method = request.urls[0].method;
183
+ const methodStr = method.toString();
184
+ if (!eq(request.urls[0].method.toUpperCase(), method)) {
185
+ warnings.push([
186
+ "method-case",
187
+ "jQuery uppercases the method, so it will be changed to " +
188
+ JSON.stringify(method.toUpperCase().toString()),
189
+ ]);
190
+ }
191
+
192
+ const contentType = request.headers.getContentType();
193
+ let exactContentType = request.headers.get("content-type");
194
+ request.headers.delete("content-type");
195
+
196
+ let url = request.urls[0].url;
197
+
198
+ let dataString: string | null = null;
199
+ let commentedOutDataString: string | null = null;
200
+ let traditional = false;
201
+
202
+ if (request.multipartUploads) {
203
+ code += getFormString(request.multipartUploads, imports);
204
+ dataString = "form";
205
+
206
+ warnings.push([
207
+ "multipart-form",
208
+ // TODO: remove this when jQuery supports FormData
209
+ "jQuery doesn't support sending FormData yet",
210
+ ]);
211
+ } else if (request.data) {
212
+ // can delete content-type header by returning null for exactContentType
213
+ [exactContentType, dataString, commentedOutDataString, traditional] =
214
+ getDataString(request.data, contentType, exactContentType, imports);
215
+ if (commentedOutDataString) {
216
+ commentedOutDataString = " // data: " + commentedOutDataString + ",\n";
217
+ }
218
+ }
219
+
220
+ if (nonDataMethods.includes(methodStr)) {
221
+ if (request.urls[0].queryList) {
222
+ if (dataString) {
223
+ warnings.push([
224
+ "data-with-get",
225
+ "jQuery doesn't allow sending data in the body with GET or HEAD requests",
226
+ ]);
227
+ if (commentedOutDataString) {
228
+ commentedOutDataString +=
229
+ " // data: " + indent(commentOut(dedent(dataString))) + ",\n";
230
+ } else {
231
+ commentedOutDataString =
232
+ " // data: " + indent(commentOut(dedent(dataString))) + ",\n";
233
+ }
234
+ }
235
+
236
+ [dataString, traditional] = serializeQuery(
237
+ [request.urls[0].queryList, request.urls[0].queryDict ?? null],
238
+ imports,
239
+ );
240
+ dataString = indent(dataString);
241
+ url = request.urls[0].urlWithoutQueryList;
242
+ } else if (request.data || request.multipartUploads) {
243
+ warnings.push([
244
+ "data-with-get",
245
+ "jQuery doesn't allow sending data with GET or HEAD requests. The data will be sent in the URL instead",
246
+ ]);
247
+ }
248
+ }
249
+
250
+ const needsConfig = !!(
251
+ request.headers.length ||
252
+ request.urls[0].auth ||
253
+ ((request.multipartUploads || request.data) &&
254
+ nonDataMethods.includes(methodStr)) ||
255
+ request.timeout ||
256
+ (exactContentType !== null && exactContentType !== undefined) ||
257
+ commentedOutDataString ||
258
+ traditional
259
+ );
260
+
261
+ let done = "";
262
+ done += ".done(function(response) {\n";
263
+ done += " console.log(response);\n";
264
+ done += "});";
265
+
266
+ if (
267
+ !needsConfig &&
268
+ method.isString() &&
269
+ ["GET", "POST"].includes(methodStr)
270
+ ) {
271
+ // TODO: .getJSON()
272
+ const fn = methodStr === "GET" ? "get" : "post";
273
+ code += "$." + fn + "(";
274
+ code += repr(url, imports);
275
+ if (dataString) {
276
+ code += ", " + dedent(dataString);
277
+ }
278
+ code += ")\n";
279
+ code += " " + indent(done) + "\n";
280
+ } else {
281
+ code += "$.ajax({\n";
282
+ code += " url: " + repr(url, imports) + ",\n";
283
+ code += " crossDomain: true,\n";
284
+
285
+ if (methodStr !== "GET") {
286
+ // jQuery uppercases methods
287
+ const sentMethod = eq(request.urls[0].method.toUpperCase(), method)
288
+ ? method.toLowerCase()
289
+ : method;
290
+ code += " method: " + repr(sentMethod, imports) + ",\n";
291
+ }
292
+
293
+ if (request.headers.length) {
294
+ code += " headers: {\n";
295
+ for (const [key, value] of request.headers) {
296
+ if (value === null) {
297
+ continue;
298
+ }
299
+ code +=
300
+ " " + repr(key, imports) + ": " + repr(value, imports) + ",\n";
301
+ }
302
+ if (code.endsWith(",\n")) {
303
+ code = code.slice(0, -2);
304
+ code += "\n";
305
+ }
306
+ code += " },\n";
307
+ }
308
+ if (exactContentType) {
309
+ code += " contentType: " + repr(exactContentType, imports) + ",\n";
310
+ }
311
+
312
+ if (request.urls[0].auth) {
313
+ const [username, password] = request.urls[0].auth;
314
+ code += " username: " + repr(username, imports) + ",\n";
315
+ code += " password: " + repr(password, imports) + ",\n";
316
+ }
317
+
318
+ if (commentedOutDataString) {
319
+ code += commentedOutDataString;
320
+ }
321
+ if (dataString) {
322
+ code += " data: " + dataString + ",\n";
323
+ }
324
+
325
+ if (traditional) {
326
+ code += " traditional: true,\n";
327
+ }
328
+
329
+ if (request.timeout) {
330
+ code +=
331
+ " timeout: " + asParseFloatTimes1000(request.timeout, imports) + ",\n";
332
+ }
333
+
334
+ if (code.endsWith(",\n")) {
335
+ code = code.slice(0, -2);
336
+ code += "\n";
337
+ }
338
+
339
+ code += "})" + done + "\n";
340
+ }
341
+
342
+ let importCode = reprImports(imports);
343
+ if (importCode) {
344
+ importCode += "\n";
345
+ }
346
+
347
+ return importCode + code;
348
+ }
349
+
350
+ export function toJavaScriptJqueryWarn(
351
+ curlCommand: string | string[],
352
+ warnings: Warnings = [],
353
+ ): [string, Warnings] {
354
+ const requests = parse(curlCommand, supportedArgs, warnings);
355
+ const jquery = _toJavaScriptJquery(requests, warnings);
356
+ return [jquery, warnings];
357
+ }
358
+ export function toJavaScriptJquery(curlCommand: string | string[]): string {
359
+ return toJavaScriptJqueryWarn(curlCommand)[0];
360
+ }
@@ -0,0 +1,315 @@
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
+
7
+ import {
8
+ repr,
9
+ asParseInt,
10
+ asParseFloatTimes1000,
11
+ toURLSearchParams,
12
+ reprObj,
13
+ toDictOrURLSearchParams,
14
+ type JSImports,
15
+ addImport,
16
+ reprImports,
17
+ FORBIDDEN_METHODS,
18
+ } from "./javascript.js";
19
+
20
+ import { getFormString } from "./jquery.js";
21
+
22
+ export const supportedArgs = new Set([
23
+ ...COMMON_SUPPORTED_ARGS,
24
+ "upload-file",
25
+ "form",
26
+ "form-string",
27
+ "next",
28
+
29
+ // --no-compressed (the default) is unsupported though
30
+ "compressed",
31
+
32
+ "upload-file",
33
+
34
+ "retry",
35
+ "max-time",
36
+ ]);
37
+
38
+ function getDataString(
39
+ request: Request,
40
+ data: Word,
41
+ imports: JSImports,
42
+ ): [string, string | null] {
43
+ const originalStringRepr = "body: " + repr(data, imports);
44
+
45
+ const contentType = request.headers.getContentType();
46
+ if (contentType === "application/json") {
47
+ try {
48
+ const dataStr = data.toString();
49
+ const parsed = JSON.parse(dataStr);
50
+ const roundtrips = JSON.stringify(parsed) === dataStr;
51
+ const jsonAsJavaScript = reprObj(parsed, 1);
52
+
53
+ const dataString = "json: " + jsonAsJavaScript;
54
+ return [dataString, roundtrips ? null : originalStringRepr];
55
+ } catch {
56
+ return [originalStringRepr, null];
57
+ }
58
+ }
59
+ if (contentType === "application/x-www-form-urlencoded") {
60
+ try {
61
+ const [queryList, queryDict] = parseQueryString(data);
62
+ if (queryList) {
63
+ // Technically node-fetch sends
64
+ // application/x-www-form-urlencoded;charset=utf-8
65
+ // TODO: handle repeated content-type header
66
+ if (
67
+ eq(
68
+ request.headers.get("content-type"),
69
+ "application/x-www-form-urlencoded",
70
+ )
71
+ ) {
72
+ request.headers.delete("content-type");
73
+ }
74
+ // TODO: check roundtrip, add a comment
75
+ // TODO: this isn't a dict anymore
76
+ return [
77
+ "body: " + toURLSearchParams([queryList, queryDict], imports),
78
+ null,
79
+ ];
80
+ }
81
+ return [originalStringRepr, null];
82
+ } catch {
83
+ return [originalStringRepr, null];
84
+ }
85
+ }
86
+ return [originalStringRepr, null];
87
+ }
88
+
89
+ export function getData(
90
+ request: Request,
91
+ isNode: boolean,
92
+ imports: JSImports,
93
+ ): [string, string | null] {
94
+ if (!request.dataArray || request.multipartUploads) {
95
+ return ["", null];
96
+ }
97
+
98
+ if (
99
+ request.dataArray.length === 1 &&
100
+ request.dataArray[0] instanceof Word &&
101
+ request.dataArray[0].isString()
102
+ ) {
103
+ try {
104
+ return getDataString(request, request.dataArray[0], imports);
105
+ } catch {}
106
+ }
107
+
108
+ const parts = [];
109
+ const hasBinary = request.dataArray.some(
110
+ (d) => !(d instanceof Word) && d.filetype === "binary",
111
+ );
112
+ const encoding = hasBinary ? "" : ", 'utf-8'";
113
+ for (const d of request.dataArray) {
114
+ if (d instanceof Word) {
115
+ parts.push(repr(d, imports));
116
+ } else {
117
+ const { filetype, name, filename } = d;
118
+ if (filetype === "urlencode" && name) {
119
+ // TODO: add this to the previous Word
120
+ parts.push(repr(name, imports));
121
+ }
122
+ // TODO: use the filetype
123
+ if (eq(filename, "-")) {
124
+ parts.push("fs.readFileSync(0" + encoding + ")");
125
+ } else {
126
+ parts.push(
127
+ "fs.readFileSync(" + repr(filename, imports) + encoding + ")",
128
+ );
129
+ }
130
+ addImport(imports, "* as fs", "fs");
131
+ }
132
+ }
133
+
134
+ if (parts.length === 0) {
135
+ return ["body: ''", null];
136
+ }
137
+
138
+ if (parts.length === 1) {
139
+ return ["body: " + parts[0], null];
140
+ }
141
+
142
+ let start = "new ArrayBuffer(";
143
+ let joiner = ", ";
144
+ let end = ")";
145
+ const totalLength = parts.reduce((a, b) => a + b.length, 0);
146
+ if (totalLength > 80) {
147
+ start += "\n ";
148
+ joiner = ",\n ";
149
+ end = "\n )";
150
+ }
151
+ return ["body: " + start + parts.join(joiner) + end, null];
152
+ }
153
+
154
+ function requestToKy(
155
+ request: Request,
156
+ warnings: Warnings,
157
+ imports: JSImports,
158
+ ): string {
159
+ warnIfPartsIgnored(request, warnings, {
160
+ multipleUrls: true,
161
+ dataReadsFile: true,
162
+ // Not actually supported, just warned per-URL
163
+ queryReadsFile: true,
164
+ });
165
+
166
+ let code = "";
167
+
168
+ if (request.multipartUploads) {
169
+ code += getFormString(request.multipartUploads, imports);
170
+ }
171
+
172
+ // Can delete content-type header
173
+ const [dataString, commentedOutDataString] = getData(request, true, imports);
174
+
175
+ for (const urlObj of request.urls) {
176
+ let optionsCode = "";
177
+
178
+ const method = urlObj.method;
179
+ const methodStr = urlObj.method.toString();
180
+ const nonDataMethods = ["GET", "HEAD"];
181
+ const methods = ["GET", "POST", "PUT", "PATCH", "HEAD", "DELETE"];
182
+
183
+ const url = urlObj.queryList ? urlObj.urlWithoutQueryList : urlObj.url;
184
+
185
+ if (method.isString() && methods.includes(methodStr)) {
186
+ const fn = methodStr.toLowerCase().toString();
187
+ code += "ky." + fn + "(" + repr(url, imports);
188
+ } else {
189
+ code += "ky(" + repr(url, imports);
190
+ optionsCode += " method: " + repr(method, imports) + ",\n";
191
+
192
+ if (method.isString() && FORBIDDEN_METHODS.includes(methodStr)) {
193
+ warnings.push([
194
+ "forbidden-method",
195
+ "the method " +
196
+ JSON.stringify(methodStr) +
197
+ " is not allowed in fetch() and therefore Ky",
198
+ ]);
199
+ }
200
+ }
201
+
202
+ if (urlObj.queryList) {
203
+ optionsCode +=
204
+ "searchParams: " +
205
+ toDictOrURLSearchParams([urlObj.queryList, urlObj.queryDict], imports);
206
+ }
207
+ if (urlObj.queryReadsFile) {
208
+ warnings.push([
209
+ "unsafe-query",
210
+ // TODO: better wording
211
+ "the URL query string is not correct, " +
212
+ JSON.stringify("@" + urlObj.queryReadsFile) +
213
+ " means it should read the file " +
214
+ JSON.stringify(urlObj.queryReadsFile),
215
+ ]);
216
+ }
217
+
218
+ if (
219
+ request.headers.length ||
220
+ (urlObj.auth && request.authType === "basic")
221
+ ) {
222
+ optionsCode += " headers: {\n";
223
+ for (const [headerName, headerValue] of request.headers) {
224
+ optionsCode +=
225
+ " " +
226
+ repr(headerName, imports) +
227
+ ": " +
228
+ repr(headerValue || new Word(), imports) +
229
+ ",\n";
230
+ }
231
+ if (urlObj.auth && request.authType === "basic") {
232
+ // TODO: if -H 'Authorization:' is passed, don't set this
233
+ optionsCode +=
234
+ " 'Authorization': 'Basic ' + btoa(" +
235
+ repr(joinWords(urlObj.auth, ":"), imports) +
236
+ "),\n";
237
+ }
238
+
239
+ if (optionsCode.endsWith(",\n")) {
240
+ optionsCode = optionsCode.slice(0, -2);
241
+ optionsCode += "\n";
242
+ }
243
+ optionsCode += " },\n";
244
+ }
245
+
246
+ if (urlObj.uploadFile) {
247
+ addImport(imports, "* as fs", "fs");
248
+ optionsCode +=
249
+ " body: fs.readFileSync(" + repr(urlObj.uploadFile, imports) + "),\n";
250
+ } else if (request.multipartUploads) {
251
+ optionsCode += " body: form,\n";
252
+ } else if (request.data) {
253
+ if (commentedOutDataString) {
254
+ optionsCode += " // " + commentedOutDataString + ",\n";
255
+ }
256
+ optionsCode += " " + dataString + ",\n";
257
+ }
258
+ if (
259
+ method.isString() &&
260
+ methodStr in nonDataMethods &&
261
+ (urlObj.uploadFile || request.data || request.multipartUploads)
262
+ ) {
263
+ warnings.push([
264
+ "non-data-method",
265
+ "Ky doesn't support sending data with GET or HEAD requests",
266
+ ]);
267
+ }
268
+
269
+ if (request.retry) {
270
+ optionsCode += " retry: " + asParseInt(request.retry, imports);
271
+ }
272
+
273
+ if (request.timeout) {
274
+ optionsCode +=
275
+ " timeout: " + asParseFloatTimes1000(request.timeout, imports);
276
+ }
277
+
278
+ if (optionsCode) {
279
+ if (optionsCode.endsWith(",\n")) {
280
+ optionsCode = optionsCode.slice(0, -2);
281
+ }
282
+ code += ", {\n";
283
+ code += optionsCode;
284
+ code += "\n}";
285
+ }
286
+
287
+ code += ");\n";
288
+ }
289
+
290
+ // TODO: generate some code for the output, like .json() if 'Accept': 'application/json'
291
+
292
+ return code;
293
+ }
294
+
295
+ export function _toNodeKy(requests: Request[], warnings?: Warnings): string {
296
+ const imports: JSImports = [];
297
+ const code = requests
298
+ .map((r) => requestToKy(r, warnings || [], imports))
299
+ .join("\n");
300
+
301
+ const importCode = "import ky from 'ky';\n" + reprImports(imports);
302
+ return importCode + "\n" + code;
303
+ }
304
+
305
+ export function toNodeKyWarn(
306
+ curlCommand: string | string[],
307
+ warnings: Warnings = [],
308
+ ): [string, Warnings] {
309
+ const requests = parse(curlCommand, supportedArgs, warnings);
310
+ const code = _toNodeKy(requests, warnings);
311
+ return [code, warnings];
312
+ }
313
+ export function toNodeKy(curlCommand: string | string[]): string {
314
+ return toNodeKyWarn(curlCommand)[0];
315
+ }