@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,506 @@
1
+ import { CCError } from "../utils.js";
2
+ import { warnIfPartsIgnored } from "../Warnings.js";
3
+ import { Word, eq, mergeWords } from "../shell/Word.js";
4
+ import { parse, COMMON_SUPPORTED_ARGS } from "../parse.js";
5
+ import type { Request, RequestUrl, Warnings } from "../parse.js";
6
+ import { Headers } from "../Headers.js";
7
+ import { parseQueryString } from "../Query.js";
8
+
9
+ import { repr, reprStr } from "./wget.js";
10
+
11
+ export const supportedArgs = new Set([
12
+ ...COMMON_SUPPORTED_ARGS,
13
+ "form",
14
+ "form-string",
15
+
16
+ "location",
17
+ "no-location",
18
+ "location-trusted",
19
+ "no-location-trusted",
20
+ "max-redirs",
21
+
22
+ "ciphers",
23
+ "insecure",
24
+ "cert",
25
+ "key",
26
+ "cacert",
27
+ "capath",
28
+
29
+ "proxy",
30
+ // "proxy-user", // not supported
31
+ "noproxy", // not supported, just better error
32
+
33
+ "timeout",
34
+ "connect-timeout",
35
+
36
+ // Wget picks the auth and some it doesn't support but there's a more
37
+ // specific error message for those.
38
+ "anyauth",
39
+ "no-anyauth",
40
+ "digest",
41
+ "no-digest",
42
+ // "aws-sigv4", // not supported
43
+ "negotiate",
44
+ "no-negotiate",
45
+ "delegation", // GSS/kerberos
46
+ // "service-name", // GSS/kerberos, not supported
47
+ "ntlm",
48
+ "no-ntlm",
49
+ "ntlm-wb",
50
+ "no-ntlm-wb",
51
+
52
+ // HTTPie looks for a netrc file by default
53
+ // TODO: this doesn't work
54
+ "no-netrc", // only explicitly disabling netrc has an effect,
55
+
56
+ "verbose",
57
+ "silent",
58
+
59
+ // "output",
60
+ "upload-file",
61
+
62
+ "next",
63
+ ]);
64
+
65
+ function escapeHeader(name: Word): Word {
66
+ // TODO: more complicated, have to check that it's not already backslashed
67
+ // and not all values might be representable
68
+ return name.replace("=", "\\=");
69
+ }
70
+ function escapeHeaderValue(value: Word): Word {
71
+ if ((value.startsWith("="), value.startsWith("@"))) {
72
+ value = value.prepend("\\");
73
+ }
74
+ return value;
75
+ }
76
+
77
+ function escapeJsonName(name: string, isFirstKey = false): string {
78
+ name = name
79
+ .replace("\\", "\\\\")
80
+ .replace("[", "\\[")
81
+ .replace("]", "\\]")
82
+ .replace(":", "\\:") // both := need to be escaped individually or you get weird results
83
+ .replace("=", "\\=");
84
+
85
+ // "A regular integer in a path (e.g [10]) means an array index;
86
+ // but if you want it to be treated as a string, you can escape
87
+ // the whole number by using a backslash (\) prefix."
88
+ // TODO: check this regex
89
+ if (!isFirstKey && /^\d+$/.test(name)) {
90
+ name = "\\" + name;
91
+ }
92
+ return name;
93
+ }
94
+ function escapeJsonStr(value: string): string {
95
+ // The backslash only has an effect on some characters and not
96
+ // the backslash itself, so it seems like there's no way to send a literal '\='
97
+ // value = value.replace("\\=", "\\\\=");
98
+ if (value.startsWith("\\=")) {
99
+ throw new CCError(
100
+ "Unrepresentable JSON string: " +
101
+ JSON.stringify(value) +
102
+ ' (starts with "\\=")',
103
+ );
104
+ }
105
+ if (value.startsWith("\\@")) {
106
+ throw new CCError(
107
+ "Unrepresentable JSON string: " +
108
+ JSON.stringify(value) +
109
+ ' (starts with "\\@")',
110
+ );
111
+ }
112
+ if (value.startsWith("=") || value.startsWith("@")) {
113
+ value = "\\" + value;
114
+ }
115
+ return value;
116
+ }
117
+ function toJson(obj: any, key = ""): string[] {
118
+ if (obj === null) {
119
+ return [reprStr(key) + ":=null"];
120
+ } else if (typeof obj === "boolean") {
121
+ return [reprStr(key) + ":=" + obj.toString()];
122
+ } else if (typeof obj === "number") {
123
+ return [reprStr(key) + ":=" + reprStr(obj.toString())];
124
+ } else if (typeof obj === "string") {
125
+ return [reprStr(key) + "=" + reprStr(escapeJsonStr(obj))];
126
+ } else if (Array.isArray(obj)) {
127
+ if (!obj.length) {
128
+ return [reprStr(key) + ":=" + "[]"];
129
+ }
130
+ return obj.map((item) => toJson(item, key + "[]")).flat();
131
+ } else {
132
+ if (!Object.keys(obj).length) {
133
+ return [reprStr(key) + ":=" + "{}"];
134
+ }
135
+ return Object.entries(obj)
136
+ .map(([name, value]) =>
137
+ toJson(
138
+ value,
139
+ key
140
+ ? key + "[" + escapeJsonName(name) + "]"
141
+ : escapeJsonName(name, true),
142
+ ),
143
+ )
144
+ .flat();
145
+ }
146
+ }
147
+ function jsonAsHttpie(flags: string[], items: string[], data: string) {
148
+ let json;
149
+ try {
150
+ json = JSON.parse(data);
151
+ } catch {}
152
+ // Only non-empty, top-level objects and arrays can be serialized as command line arguments
153
+ if (
154
+ (typeof json === "object" && json !== null && Object.keys(json).length) ||
155
+ (Array.isArray(json) && json.length)
156
+ ) {
157
+ let jsonItems;
158
+ try {
159
+ jsonItems = toJson(json);
160
+ } catch {}
161
+ if (jsonItems) {
162
+ for (const jsonItem of jsonItems) {
163
+ items.push(jsonItem);
164
+ }
165
+ return;
166
+ }
167
+ }
168
+ flags.push("--raw " + (reprStr(data) || "''"));
169
+ }
170
+
171
+ function escapeQueryName(name: Word): Word {
172
+ // an unquoted ":" turns into ": "
173
+ return name.replace("\\", "\\\\").replace(":", "\\:").replace("=", "\\=");
174
+ }
175
+ function escapeQueryValue(value: Word): Word {
176
+ // TODO: the backslash only has an effect on some characters and not
177
+ // the backslash itself, so it seems like there's no way to send a literal '\='
178
+ // value = value.replace("\\=", "\\\\=");
179
+ if ((value.startsWith("="), value.startsWith("@"))) {
180
+ value = value.prepend("\\");
181
+ }
182
+ return value;
183
+ }
184
+ function urlencodedAsHttpie(flags: string[], items: string[], data: Word) {
185
+ let queryList;
186
+ try {
187
+ [queryList] = parseQueryString(data);
188
+ } catch {}
189
+ if (!queryList) {
190
+ flags.push("--raw " + (repr(data) || "''"));
191
+ return;
192
+ }
193
+
194
+ flags.push("--form");
195
+ for (const [name, value] of queryList) {
196
+ items.push(
197
+ repr(mergeWords(escapeQueryName(name), "=", escapeQueryValue(value))),
198
+ );
199
+ }
200
+ }
201
+
202
+ function formatData(
203
+ flags: string[],
204
+ items: string[],
205
+ data: Word,
206
+ headers: Headers,
207
+ ) {
208
+ const contentType = headers.getContentType();
209
+ if (contentType === "application/json" && data.isString()) {
210
+ jsonAsHttpie(flags, items, data.toString());
211
+ } else if (contentType === "application/x-www-form-urlencoded") {
212
+ urlencodedAsHttpie(flags, items, data);
213
+ } else {
214
+ flags.push("--raw " + (repr(data) || "''"));
215
+ }
216
+ }
217
+
218
+ // TODO: does this work?
219
+ function escapeFormName(name: Word): Word {
220
+ return name.replace("\\", "\\\\").replace("@", "\\@").replace("=", "\\=");
221
+ }
222
+
223
+ function requestToHttpie(
224
+ request: Request,
225
+ url: RequestUrl,
226
+ warnings: Warnings,
227
+ ): string {
228
+ const flags: string[] = [];
229
+ let method: string | null = null;
230
+ let urlArg = url.url;
231
+ const items: string[] = [];
232
+
233
+ if (url.uploadFile || request.data || request.multipartUploads) {
234
+ if (!eq(url.method, "POST")) {
235
+ method = repr(url.method);
236
+ }
237
+ } else if (!eq(url.method, "GET")) {
238
+ method = repr(url.method);
239
+ }
240
+
241
+ // TODO: don't merge headers
242
+ if (request.headers.length) {
243
+ for (const [headerName, headerValue] of request.headers) {
244
+ if (headerValue === null) {
245
+ items.push(repr(mergeWords(escapeHeader(headerName), ":")));
246
+ } else if (!headerValue.toBool()) {
247
+ items.push(repr(mergeWords(escapeHeader(headerName), ";")));
248
+ } else {
249
+ items.push(
250
+ repr(
251
+ mergeWords(
252
+ escapeHeader(headerName),
253
+ ":",
254
+ escapeHeaderValue(headerValue),
255
+ ),
256
+ ),
257
+ );
258
+ }
259
+ }
260
+ }
261
+
262
+ if (url.auth) {
263
+ const [user, password] = url.auth;
264
+
265
+ if (request.authType === "digest") {
266
+ flags.push("-A digest");
267
+ } else if (request.authType === "ntlm" || request.authType === "ntlm-wb") {
268
+ flags.push("--auth-type=ntlm");
269
+ warnings.push([
270
+ "httpie-ntlm",
271
+ "NTLM auth requires the httpie-ntlm plugin",
272
+ ]);
273
+ } else if (request.authType === "negotiate") {
274
+ flags.push("--auth-type=negotiate");
275
+ warnings.push([
276
+ "httpie-negotiate",
277
+ "SPNEGO (GSS Negotiate) auth requires the httpie-negotiate plugin",
278
+ ]);
279
+ // TODO: is this the same thing?
280
+ // } else if (request.authType === "aws-sigv4") {
281
+ // warnings.push([
282
+ // "httpie-ntlm",
283
+ // "aws-sigv4 auth is not supported and requires the httpie-aws-auth plugin",
284
+ // ]);
285
+ } else if (request.authType !== "basic") {
286
+ warnings.push([
287
+ "httpie-unsupported-auth",
288
+ "HTTPie doesn't support " + request.authType + " authentication",
289
+ ]);
290
+ }
291
+ // TODO: -A bearer -a token
292
+
293
+ flags.push("-a " + repr(mergeWords(user, ":", password)));
294
+ }
295
+
296
+ if (url.queryList) {
297
+ urlArg = url.urlWithoutQueryList;
298
+ for (const [name, value] of url.queryList) {
299
+ items.push(
300
+ repr(mergeWords(escapeQueryName(name), "==", escapeQueryValue(value))),
301
+ );
302
+ }
303
+ }
304
+
305
+ if (url.uploadFile) {
306
+ if (eq(url.uploadFile, "-") || eq(url.uploadFile, ".")) {
307
+ warnings.push([
308
+ "httpie-stdin",
309
+ "pass in the file contents to HTTPie through stdin",
310
+ ]);
311
+ } else {
312
+ items.push("@" + repr(url.uploadFile));
313
+ }
314
+ } else if (request.multipartUploads) {
315
+ flags.push("--multipart");
316
+ for (const m of request.multipartUploads) {
317
+ if ("content" in m) {
318
+ items.push(repr(escapeFormName(m.name)) + "=" + repr(m.content));
319
+ } else {
320
+ if ("filename" in m && m.filename) {
321
+ items.push(repr(escapeFormName(m.name)) + "@" + repr(m.filename));
322
+ if (!eq(m.filename, m.contentFile)) {
323
+ warnings.push([
324
+ "httpie-multipart-fake-filename",
325
+ "HTTPie doesn't support multipart uploads that read a certain filename but send a different filename",
326
+ ]);
327
+ }
328
+ } else {
329
+ items.push(repr(escapeFormName(m.name)) + "=@" + repr(m.contentFile));
330
+ }
331
+ }
332
+ }
333
+ } else if (
334
+ request.dataArray &&
335
+ request.dataArray.length === 1 &&
336
+ !(request.dataArray[0] instanceof Word) &&
337
+ !request.dataArray[0].name
338
+ ) {
339
+ // TODO: surely --upload-file and this can't be identical,
340
+ // doesn't this ignore url encoding?
341
+ items.push("@" + repr(request.dataArray[0].filename));
342
+ } else if (request.data) {
343
+ formatData(flags, items, request.data, request.headers);
344
+ }
345
+
346
+ if (request.followRedirects || request.followRedirectsTrusted) {
347
+ flags.push("--follow");
348
+ }
349
+ if (request.maxRedirects && request.maxRedirects.toString() !== "30") {
350
+ // TODO: escape/parse?
351
+ flags.push("--max-redirects=" + repr(request.maxRedirects));
352
+ }
353
+
354
+ if (request.netrc === "ignored") {
355
+ flags.push("--ignore-netrc");
356
+ }
357
+
358
+ if (request.proxy) {
359
+ flags.push("--proxy=http:" + repr(request.proxy));
360
+ flags.push("--proxy=https:" + repr(request.proxy));
361
+ }
362
+ if (request.proxyAuth) {
363
+ // TODO: add to proxy URL
364
+ }
365
+ if (request.noproxy) {
366
+ warnings.push([
367
+ "httpie-noproxy",
368
+ "HTTPie requires passing noproxy through environment variables: " +
369
+ JSON.stringify(request.noproxy.toString()),
370
+ ]);
371
+ }
372
+
373
+ if (request.insecure) {
374
+ flags.push("--verify=no");
375
+ }
376
+ if (request.cacert) {
377
+ flags.push("--verify=" + repr(request.cacert));
378
+ }
379
+ if (request.capath) {
380
+ flags.push("--verify=" + repr(request.capath));
381
+ }
382
+
383
+ if (request.cert) {
384
+ flags.push("--cert=" + repr(request.cert[0]));
385
+ }
386
+ if (request.key) {
387
+ flags.push("--cert-key=" + repr(request.key));
388
+ }
389
+ if (request.cert && request.cert[1]) {
390
+ flags.push("--cert-key-pass=" + repr(request.cert[1]));
391
+ }
392
+ // TODO: --ssl= for the version
393
+ if (request.ciphers) {
394
+ flags.push("--ciphers=" + repr(request.ciphers));
395
+ }
396
+
397
+ if (request.connectTimeout) {
398
+ flags.push("--timeout=" + repr(request.connectTimeout));
399
+ }
400
+ if (request.timeout) {
401
+ if (request.connectTimeout) {
402
+ warnings.push([
403
+ "httpie-timeout-with-connect-timeout",
404
+ "ignoring --timeout because HTTPie's timeout is more similar to curl's --connect-timeout",
405
+ ]);
406
+ } else {
407
+ flags.push("--timeout=" + repr(request.timeout));
408
+ // warn that this is not for the whole request
409
+ warnings.push([
410
+ "httpie-timeout",
411
+ "HTTPie's timeout is just for the connection, not for the whole request",
412
+ ]);
413
+ }
414
+ }
415
+
416
+ if (request.verbose) {
417
+ flags.push("--verbose");
418
+ }
419
+ if (request.silent) {
420
+ flags.push("--quiet");
421
+ }
422
+
423
+ function localhostShorthand(u: Word): Word {
424
+ if (u.startsWith("localhost:")) {
425
+ return u.slice("localhost".length);
426
+ } else if (u.startsWith("localhost/") || eq(u, "localhost")) {
427
+ return u.slice("localhost".length).prepend(":");
428
+ }
429
+ return u;
430
+ }
431
+ let command = "http";
432
+ if (urlArg.startsWith("https://")) {
433
+ command = "https";
434
+ urlArg = localhostShorthand(urlArg.slice("https://".length));
435
+ } else if (urlArg.startsWith("http://")) {
436
+ urlArg = localhostShorthand(urlArg.slice("http://".length));
437
+ }
438
+
439
+ if (url.output) {
440
+ // TODO: pipe output
441
+ }
442
+
443
+ if (method) {
444
+ flags.push(method);
445
+ }
446
+ // If any of the field names or headers starts with a dash, add a -- argument
447
+ // TODO: this might have edge cases
448
+ if (items.some((i) => i.startsWith("-"))) {
449
+ items.unshift("--");
450
+ }
451
+ const args = [...flags, repr(urlArg), ...items];
452
+ const multiline =
453
+ args.length > 3 || args.reduce((a, b) => a + b.length, 0) > 80 - 5;
454
+ const joiner = multiline ? " \\\n " : " ";
455
+ return command + " " + args.join(joiner) + "\n";
456
+ }
457
+
458
+ export function _toHttpie(
459
+ requests: Request[],
460
+ warnings: Warnings = [],
461
+ ): string {
462
+ const commands = [];
463
+
464
+ for (const request of requests) {
465
+ warnIfPartsIgnored(request, warnings, {
466
+ dataReadsFile: true,
467
+ // HTTPie has its own session.json file format
468
+ // cookieFiles: true,
469
+ multipleUrls: true,
470
+ });
471
+ if (
472
+ request.dataReadsFile &&
473
+ request.dataArray &&
474
+ request.dataArray.length &&
475
+ (request.dataArray.length > 1 ||
476
+ (!(request.dataArray[0] instanceof Word) && request.dataArray[0].name))
477
+ ) {
478
+ warnings.push([
479
+ "unsafe-data",
480
+ "the generated data content is wrong, " +
481
+ // TODO: might not come from "@"
482
+ JSON.stringify("@" + request.dataReadsFile) +
483
+ " means read the file " +
484
+ JSON.stringify(request.dataReadsFile),
485
+ ]);
486
+ }
487
+
488
+ for (const url of request.urls) {
489
+ commands.push(requestToHttpie(request, url, warnings));
490
+ }
491
+ }
492
+ return commands.join("\n\n");
493
+ }
494
+
495
+ export function toHttpieWarn(
496
+ curlCommand: string | string[],
497
+ warnings: Warnings = [],
498
+ ): [string, Warnings] {
499
+ const requests = parse(curlCommand, supportedArgs, warnings);
500
+ const httpie = _toHttpie(requests, warnings);
501
+ return [httpie, warnings];
502
+ }
503
+
504
+ export function toHttpie(curlCommand: string | string[]): string {
505
+ return toHttpieWarn(curlCommand)[0];
506
+ }
@@ -0,0 +1,151 @@
1
+ import { joinWords } from "../../shell/Word.js";
2
+ import { parse, getFirst, COMMON_SUPPORTED_ARGS } from "../../parse.js";
3
+ import type { Request, Warnings } from "../../parse.js";
4
+
5
+ import { repr } from "./java.js";
6
+
7
+ export const supportedArgs = new Set([
8
+ ...COMMON_SUPPORTED_ARGS,
9
+ // TODO
10
+ // "form",
11
+ // "form-string",
12
+ ]);
13
+
14
+ export function _toJavaHttpUrlConnection(
15
+ requests: Request[],
16
+ warnings: Warnings = [],
17
+ ): string {
18
+ const request = getFirst(requests, warnings);
19
+
20
+ const imports = new Set<string>([
21
+ "java.io.IOException",
22
+ "java.io.InputStream",
23
+ "java.net.HttpURLConnection",
24
+ "java.net.URL",
25
+ "java.util.Scanner",
26
+ ]);
27
+
28
+ let javaCode = "";
29
+
30
+ javaCode +=
31
+ " URL url = new URL(" + repr(request.urls[0].url, imports) + ");\n";
32
+ javaCode +=
33
+ " HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();\n";
34
+ javaCode +=
35
+ " httpConn.setRequestMethod(" +
36
+ repr(request.urls[0].method, imports) +
37
+ ");\n\n";
38
+
39
+ let gzip = false;
40
+ if (request.headers.length) {
41
+ for (const [headerName, headerValue] of request.headers) {
42
+ if (headerValue === null) {
43
+ continue;
44
+ }
45
+ javaCode +=
46
+ " httpConn.setRequestProperty(" +
47
+ repr(headerName, imports) +
48
+ ", " +
49
+ repr(headerValue, imports) +
50
+ ");\n";
51
+ if (
52
+ headerName.toLowerCase().toString() === "accept-encoding" &&
53
+ headerValue
54
+ ) {
55
+ gzip = headerValue.indexOf("gzip") !== -1;
56
+ }
57
+ }
58
+ javaCode += "\n";
59
+ }
60
+
61
+ if (request.urls[0].auth) {
62
+ javaCode +=
63
+ " byte[] message = (" +
64
+ repr(joinWords(request.urls[0].auth, ":"), imports) +
65
+ ').getBytes("UTF-8");\n';
66
+ javaCode +=
67
+ " String basicAuth = DatatypeConverter.printBase64Binary(message);\n";
68
+ javaCode +=
69
+ ' httpConn.setRequestProperty("Authorization", "Basic " + basicAuth);\n';
70
+ javaCode += "\n";
71
+
72
+ imports.add("javax.xml.bind.DatatypeConverter");
73
+ }
74
+
75
+ if (request.data) {
76
+ javaCode += " httpConn.setDoOutput(true);\n";
77
+ javaCode +=
78
+ " OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());\n";
79
+ javaCode += " writer.write(" + repr(request.data, imports) + ");\n";
80
+ javaCode += " writer.flush();\n";
81
+ javaCode += " writer.close();\n";
82
+ javaCode += " httpConn.getOutputStream().close();\n";
83
+ javaCode += "\n";
84
+
85
+ imports.add("java.io.OutputStreamWriter");
86
+ }
87
+
88
+ javaCode +=
89
+ " InputStream responseStream = httpConn.getResponseCode() / 100 == 2\n";
90
+ javaCode += " ? httpConn.getInputStream()\n";
91
+ javaCode += " : httpConn.getErrorStream();\n";
92
+ if (gzip) {
93
+ javaCode += ' if ("gzip".equals(httpConn.getContentEncoding())) {\n';
94
+ javaCode +=
95
+ " responseStream = new GZIPInputStream(responseStream);\n";
96
+ javaCode += " }\n";
97
+
98
+ imports.add("java.util.zip.GZIPInputStream");
99
+ }
100
+ javaCode +=
101
+ ' Scanner s = new Scanner(responseStream).useDelimiter("\\\\A");\n';
102
+ javaCode += ' String response = s.hasNext() ? s.next() : "";\n';
103
+ javaCode += " System.out.println(response);\n";
104
+
105
+ javaCode += " }\n";
106
+ javaCode += "}";
107
+
108
+ let preambleCode = "";
109
+ for (const imp of Array.from(imports).sort()) {
110
+ preambleCode += "import " + imp + ";\n";
111
+ }
112
+ if (imports.size) {
113
+ preambleCode += "\n";
114
+ }
115
+
116
+ preambleCode += "class Main {\n";
117
+ preambleCode += "\n";
118
+ if (imports.has("java.lang.Runtime")) {
119
+ // Helper function that runs a bash command and always returns a string
120
+ preambleCode += " public static String exec(String cmd) {\n";
121
+ preambleCode += " try {\n";
122
+ preambleCode += " Process p = Runtime.getRuntime().exec(cmd);\n";
123
+ preambleCode += " p.waitFor();\n";
124
+ preambleCode +=
125
+ ' Scanner s = new Scanner(p.getInputStream()).useDelimiter("\\\\A");\n';
126
+ preambleCode += ' return s.hasNext() ? s.next() : "";\n';
127
+ preambleCode += " } catch (Exception e) {\n";
128
+ preambleCode += ' return "";\n';
129
+ preambleCode += " }\n";
130
+ preambleCode += " }\n";
131
+ preambleCode += "\n";
132
+ }
133
+ preambleCode +=
134
+ " public static void main(String[] args) throws IOException {\n";
135
+
136
+ return preambleCode + javaCode + "\n";
137
+ }
138
+ export function toJavaHttpUrlConnectionWarn(
139
+ curlCommand: string | string[],
140
+ warnings: Warnings = [],
141
+ ): [string, Warnings] {
142
+ const requests = parse(curlCommand, supportedArgs, warnings);
143
+ const java = _toJavaHttpUrlConnection(requests, warnings);
144
+ return [java, warnings];
145
+ }
146
+
147
+ export function toJavaHttpUrlConnection(
148
+ curlCommand: string | string[],
149
+ ): string {
150
+ return toJavaHttpUrlConnectionWarn(curlCommand)[0];
151
+ }