@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,1371 @@
1
+ import { Word, eq, mergeWords } from "../shell/Word.js";
2
+ import { parse, getFirst, COMMON_SUPPORTED_ARGS } from "../parse.js";
3
+ import type { Request, Warnings } from "../parse.js";
4
+
5
+ export const supportedArgs = new Set([
6
+ ...COMMON_SUPPORTED_ARGS,
7
+
8
+ "disallow-username-in-url",
9
+ "path-as-is",
10
+
11
+ "alt-svc",
12
+
13
+ "unix-socket",
14
+ "abstract-unix-socket",
15
+
16
+ "compressed",
17
+ "no-compressed",
18
+ "verbose",
19
+ "no-verbose",
20
+
21
+ "proxy",
22
+ "proxy-user",
23
+ "proxytunnel",
24
+ "noproxy",
25
+ "preproxy",
26
+ "proxy-anyauth",
27
+ "proxy-basic",
28
+ "proxy-digest",
29
+ "proxy-negotiate",
30
+ "proxy-ntlm",
31
+ "proxy-ca-native",
32
+ "proxy-cacert",
33
+ "proxy-capath",
34
+ "proxy-cert-type",
35
+ "proxy-cert",
36
+ "proxy-ciphers",
37
+ "proxy-crlfile",
38
+ "proxy-header",
39
+ "proxy-http2",
40
+ "proxy-insecure",
41
+ "proxy-key",
42
+ "proxy-key-type",
43
+ "proxy-pass",
44
+ "proxy-pinnedpubkey",
45
+ "proxy-service-name",
46
+ "proxy-ssl-allow-beast",
47
+ "proxy-ssl-auto-client-cert",
48
+ "proxy-tls13-ciphers",
49
+ "proxy-tlsuser",
50
+ "proxy-tlspassword",
51
+ "proxy-tlsauthtype",
52
+ "proxy-tlsv1",
53
+ "socks4",
54
+ "socks4a",
55
+ "socks5",
56
+ "socks5-hostname",
57
+ "socks5-basic",
58
+ "socks5-gssapi",
59
+ "socks5-gssapi-nec",
60
+ "socks5-gssapi-service",
61
+
62
+ "haproxy-clientip",
63
+ "haproxy-protocol",
64
+
65
+ "interface",
66
+
67
+ "netrc",
68
+ "netrc-file",
69
+ "netrc-optional",
70
+
71
+ // "anyauth",
72
+ // "no-anyauth",
73
+ "digest",
74
+ "no-digest",
75
+ "negotiate",
76
+ "no-negotiate",
77
+ "service-name",
78
+ "ntlm",
79
+ "no-ntlm",
80
+ "ntlm-wb",
81
+ "no-ntlm-wb",
82
+ "aws-sigv4",
83
+ "delegation",
84
+ "oauth2-bearer",
85
+
86
+ "ipv4",
87
+ "ipv6",
88
+
89
+ "local-port",
90
+
91
+ "ftp-skip-pasv-ip",
92
+
93
+ "sasl-authzid",
94
+ "sasl-ir",
95
+ "tr-encoding",
96
+
97
+ "tcp-fastopen",
98
+
99
+ // Not parsed properly
100
+ // "proto",
101
+ // "proto-redir",
102
+ "proto-default",
103
+
104
+ "ignore-content-length",
105
+ "no-ignore-content-length",
106
+
107
+ "remote-time",
108
+ // "time-cond",
109
+
110
+ // requires that the underlying libcurl was built to support c-ares
111
+ // "dns-interface",
112
+ // "dns-ipv4-addr",
113
+ // "dns-ipv6-addr",
114
+ // "dns-servers",
115
+
116
+ // No effect
117
+ // "dump-header",
118
+ // "include",
119
+ // "engine",
120
+
121
+ // Adds a If-None-Match header
122
+ // "etag-compare",
123
+ // "etag-save", // No effect
124
+
125
+ "fail",
126
+ // "fail-with-body",
127
+ // "fail-early",
128
+
129
+ "continue-at",
130
+
131
+ "speed-limit",
132
+ "speed-time",
133
+ "limit-rate",
134
+ "max-filesize",
135
+
136
+ "http0.9",
137
+ "http1.0",
138
+ "http1.1",
139
+ "http2",
140
+ "http2-prior-knowledge",
141
+ "http3",
142
+ "http3-only",
143
+
144
+ "cookie-jar",
145
+ "junk-session-cookies",
146
+
147
+ "crlf",
148
+ "no-crlf",
149
+ "use-ascii",
150
+
151
+ // "write-out",
152
+
153
+ "pass",
154
+ "cacert",
155
+ "capath",
156
+ "crlfile",
157
+ "pinnedpubkey",
158
+ "curves",
159
+ "cert",
160
+ "cert-status",
161
+ "cert-type",
162
+ "key",
163
+ "key-type",
164
+ "ca-native",
165
+ "ssl-allow-beast",
166
+ "ciphers",
167
+ "tls13-ciphers",
168
+ "tlsuser",
169
+ "tlspassword",
170
+ "tlsauthtype",
171
+ "ssl",
172
+ "ssl-auto-client-cert",
173
+ "ssl-no-revoke",
174
+ "ssl-reqd",
175
+ "ssl-revoke-best-effort",
176
+
177
+ // "sslv2", // ignored
178
+ // "sslv3", // ignored
179
+ "tlsv1",
180
+ "tlsv1.0",
181
+ "tlsv1.1",
182
+ "tlsv1.2",
183
+ "tlsv1.3",
184
+ "tls-max",
185
+
186
+ // "false-start",
187
+ "hsts",
188
+ "alpn",
189
+ "no-alpn",
190
+
191
+ "form",
192
+ "form-string",
193
+ "form-escape",
194
+ "no-form-escape",
195
+
196
+ "doh-url",
197
+ "doh-cert-status",
198
+ // "doh-insecure", // has no effect
199
+
200
+ "location",
201
+ "no-location",
202
+ "location-trusted",
203
+ "no-location-trusted",
204
+ "max-redirs",
205
+ "post301",
206
+ "post302",
207
+ "post303",
208
+
209
+ "max-time",
210
+ "connect-timeout",
211
+ "expect100-timeout",
212
+ "happy-eyeballs-timeout-ms",
213
+
214
+ "resolve",
215
+ "connect-to",
216
+
217
+ "keepalive",
218
+ "no-keepalive",
219
+ "keepalive-time",
220
+
221
+ "insecure",
222
+ "no-insecure",
223
+ ]);
224
+
225
+ const regexEscape = /"|\\|\p{C}|[^ \P{Z}]/gu;
226
+ export function reprStr(s: string): string {
227
+ return (
228
+ '"' +
229
+ s.replace(regexEscape, (c: string): string => {
230
+ switch (c) {
231
+ case "\x07":
232
+ return "\\a";
233
+ case "\b":
234
+ return "\\b";
235
+ case "\f":
236
+ return "\\f";
237
+ case "\n":
238
+ return "\\n";
239
+ case "\r":
240
+ return "\\r";
241
+ case "\t":
242
+ return "\\t";
243
+ case "\v":
244
+ return "\\v";
245
+ case "\\":
246
+ return "\\\\";
247
+ case '"':
248
+ return '\\"';
249
+ }
250
+ const hex = (c.codePointAt(0) as number).toString(16);
251
+ if (hex.length <= 2) {
252
+ return "\\x" + hex.padStart(2, "0");
253
+ }
254
+ if (hex.length <= 4) {
255
+ return "\\u" + hex.padStart(4, "0");
256
+ }
257
+ return "\\U" + hex.padStart(8, "0");
258
+ }) +
259
+ '"'
260
+ );
261
+ }
262
+
263
+ export function repr(word: Word, imports: Set<string>): string {
264
+ const reprs = [];
265
+ for (const t of word.tokens) {
266
+ if (typeof t === "string") {
267
+ reprs.push(reprStr(t));
268
+ } else if (t.type === "variable") {
269
+ reprs.push("getenv(" + reprStr(t.value) + ")");
270
+ imports.add("stdlib.h");
271
+ } else if (t.type === "command") {
272
+ // TODO: read the FILE contents
273
+ reprs.push("popen(" + reprStr(t.value) + ', "r")');
274
+ imports.add("stdio.h");
275
+ }
276
+ }
277
+
278
+ // TODO: C can't concatenate strings
279
+ return reprs.join(" + ");
280
+ }
281
+
282
+ export function atof1000(word: Word, imports: Set<string>): string {
283
+ if (word.isString()) {
284
+ // TODO: check it's actually a valid float
285
+ const asFloat = parseFloat(word.toString());
286
+ if (!Number.isNaN(asFloat)) {
287
+ return Math.floor(asFloat * 1000) + "L";
288
+ }
289
+ }
290
+ return "(long)(atof(" + repr(word, imports) + ") * 1000)";
291
+ }
292
+
293
+ export function atoi(word: Word, imports: Set<string>): string {
294
+ if (word.isString()) {
295
+ // TODO: check it's actually a valid int
296
+ return word.toString();
297
+ }
298
+ return "atoi(" + repr(word, imports) + ")";
299
+ }
300
+ export function atol(word: Word, imports: Set<string>): string {
301
+ if (word.isString()) {
302
+ // TODO: check it's actually a valid int
303
+ return word.toString() + "L";
304
+ }
305
+ return "atol(" + repr(word, imports) + ")";
306
+ }
307
+
308
+ const AUTH_TO_VAR = {
309
+ basic: "CURLAUTH_BASIC",
310
+ negotiate: "CURLAUTH_NEGOTIATE",
311
+ // technically what --libcurl generates but older
312
+ // negotiate: "CURLAUTH_GSSNEGOTIATE",
313
+ digest: "CURLAUTH_DIGEST",
314
+ ntlm: "CURLAUTH_NTLM",
315
+ "ntlm-wb": "CURLAUTH_NTLM_WB",
316
+ bearer: "CURLAUTH_BEARER",
317
+ "aws-sigv4": "CURLAUTH_AWS_SIGV4",
318
+ none: "CURLAUTH_NONE",
319
+ };
320
+
321
+ function requestToC(
322
+ request: Request,
323
+ warnings: Warnings = [],
324
+ imports: Set<string>,
325
+ ): string {
326
+ let preamble = "";
327
+ preamble += "int main(int argc, char *argv[])\n";
328
+ preamble += "{\n";
329
+ preamble += " CURLcode ret;\n";
330
+ preamble += " CURL *hnd;\n";
331
+
332
+ let vars = "";
333
+
334
+ let code = "";
335
+ code += " hnd = curl_easy_init();\n";
336
+
337
+ let cleanup = "";
338
+ cleanup += " curl_easy_cleanup(hnd);\n";
339
+ cleanup += " hnd = NULL;\n";
340
+
341
+ if (request.tcpFastopen) {
342
+ code += " curl_easy_setopt(hnd, CURLOPT_TCP_FASTOPEN, 1L);\n";
343
+ }
344
+ const bufferSize = request.limitRate
345
+ ? atol(request.limitRate, imports) // TODO: parse
346
+ : "102400L";
347
+ code += " curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, " + bufferSize + ");\n";
348
+
349
+ if (request.localPort) {
350
+ const [start, end] = request.localPort;
351
+
352
+ code +=
353
+ " curl_easy_setopt(hnd, CURLOPT_LOCALPORT, " +
354
+ atol(start, imports) +
355
+ ");\n";
356
+ let range = "1L";
357
+ if (end) {
358
+ range = atol(end, imports) + "-" + atol(start, imports);
359
+ }
360
+ code += " curl_easy_setopt(hnd, CURLOPT_LOCALPORTRANGE, " + range + ");\n";
361
+ }
362
+
363
+ // TODO: if it doesn't have a query string from --data, it's better to
364
+ // do originalUrl because it doesn't need to have the http[s]://
365
+ const url = request.urls[0].url;
366
+ code += " curl_easy_setopt(hnd, CURLOPT_URL, " + repr(url, imports) + ");\n";
367
+
368
+ code += " curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);\n";
369
+
370
+ if (request.oauth2Bearer) {
371
+ code +=
372
+ " curl_easy_setopt(hnd, CURLOPT_XOAUTH2_BEARER, " +
373
+ repr(request.oauth2Bearer, imports) +
374
+ ");\n";
375
+ }
376
+
377
+ if (request.proxy) {
378
+ const proxy = repr(request.proxy, imports);
379
+ code += " curl_easy_setopt(hnd, CURLOPT_PROXY, " + proxy + ");\n";
380
+ }
381
+ if (request.proxyType) {
382
+ if (request.proxyType === "http2") {
383
+ code += " curl_easy_setopt(hnd, CURLOPT_PROXYTYPE, 3L);\n";
384
+ } else if (request.proxyType === "http1") {
385
+ code +=
386
+ " curl_easy_setopt(hnd, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP_1_0);\n";
387
+ } else if (request.proxyType === "socks4") {
388
+ code +=
389
+ " curl_easy_setopt(hnd, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4);\n";
390
+ } else if (request.proxyType === "socks4a") {
391
+ code +=
392
+ " curl_easy_setopt(hnd, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4A);\n";
393
+ } else if (request.proxyType === "socks5") {
394
+ code +=
395
+ " curl_easy_setopt(hnd, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5);\n";
396
+ } else if (request.proxyType === "socks5-hostname") {
397
+ code +=
398
+ " curl_easy_setopt(hnd, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5_HOSTNAME);\n";
399
+ }
400
+ }
401
+ if (request.proxyAuth) {
402
+ const proxyUserpwd = repr(request.proxyAuth, imports);
403
+ code +=
404
+ " curl_easy_setopt(hnd, CURLOPT_PROXYUSERPWD, " + proxyUserpwd + ");\n";
405
+ }
406
+ if (request.proxytunnel) {
407
+ code += " curl_easy_setopt(hnd, CURLOPT_HTTPPROXYTUNNEL, 1L);\n";
408
+ }
409
+ if (request.proxyAuth) {
410
+ const proxyAuth = AUTH_TO_VAR[request.proxyAuthType];
411
+ code +=
412
+ " curl_easy_setopt(hnd, CURLOPT_PROXYAUTH, (long)" + proxyAuth + ");\n";
413
+ }
414
+
415
+ if (request.preproxy) {
416
+ const preproxy = repr(request.preproxy, imports);
417
+ code += " curl_easy_setopt(hnd, CURLOPT_PRE_PROXY, " + preproxy + ");\n";
418
+ }
419
+ if (request.noproxy) {
420
+ const noproxy = repr(request.noproxy, imports);
421
+ code += " curl_easy_setopt(hnd, CURLOPT_NOPROXY, " + noproxy + ");\n";
422
+ }
423
+ if (request.fail) {
424
+ code += " curl_easy_setopt(hnd, CURLOPT_FAILONERROR, 1L);\n";
425
+ }
426
+ if (request.netrc) {
427
+ const netrc = {
428
+ optional: "CURL_NETRC_OPTIONAL",
429
+ required: "CURL_NETRC_REQUIRED",
430
+ ignored: "CURL_NETRC_IGNORED",
431
+ }[request.netrc || "ignored"];
432
+ code += " curl_easy_setopt(hnd, CURLOPT_NETRC, (long)" + netrc + ");\n";
433
+ }
434
+ if (request.netrcFile) {
435
+ const netrcFile = repr(request.netrcFile, imports);
436
+ code += " curl_easy_setopt(hnd, CURLOPT_NETRC_FILE, " + netrcFile + ");\n";
437
+ }
438
+
439
+ if (request.useAscii) {
440
+ code += " curl_easy_setopt(hnd, CURLOPT_TRANSFERTEXT, 1L);\n";
441
+ }
442
+
443
+ if (request.urls[0].auth) {
444
+ const [username, password] = request.urls[0].auth;
445
+ const userpwd = repr(mergeWords(username, ":", password), imports);
446
+ code += " curl_easy_setopt(hnd, CURLOPT_USERPWD, " + userpwd + ");\n";
447
+ }
448
+
449
+ if (request.timeout) {
450
+ code +=
451
+ " curl_easy_setopt(hnd, CURLOPT_TIMEOUT_MS, " +
452
+ atof1000(request.timeout, imports) +
453
+ ");\n";
454
+ }
455
+
456
+ if (request.urls[0].uploadFile) {
457
+ // TODO
458
+ } else if (request.multipartUploads) {
459
+ preamble += " curl_mime *mime1;\n";
460
+ preamble += " curl_mimepart *part1;\n";
461
+
462
+ vars += " mime1 = NULL;\n";
463
+
464
+ code += " mime1 = curl_mime_init(hnd);\n";
465
+
466
+ for (const m of request.multipartUploads) {
467
+ code += " part1 = curl_mime_addpart(mime1);\n";
468
+ if ("contentFile" in m && m.contentFile) {
469
+ code +=
470
+ " curl_mime_filedata(part1, " +
471
+ repr(m.contentFile, imports) +
472
+ ");\n";
473
+ } else if ("content" in m && m.content) {
474
+ code +=
475
+ " curl_mime_data(part1, " +
476
+ repr(m.content, imports) +
477
+ ", CURL_ZERO_TERMINATED);\n";
478
+ }
479
+ if ("encoder" in m && m.encoder) {
480
+ code +=
481
+ " curl_mime_encoder(part1, " + repr(m.encoder, imports) + ");\n";
482
+ }
483
+ if (
484
+ "filename" in m &&
485
+ m.filename &&
486
+ !("contentFile" in m && m.contentFile && eq(m.filename, m.contentFile))
487
+ ) {
488
+ code +=
489
+ " curl_mime_filename(part1, " + repr(m.filename, imports) + ");\n";
490
+ } else if (!m.filename && "contentFile" in m && m.contentFile) {
491
+ code += " curl_mime_filename(part1, NULL);\n";
492
+ }
493
+ code += " curl_mime_name(part1, " + repr(m.name, imports) + ");\n";
494
+ if ("contentType" in m && m.contentType) {
495
+ code +=
496
+ " curl_mime_type(part1, " + repr(m.contentType, imports) + ");\n";
497
+ }
498
+ if ("headers" in m && m.headers) {
499
+ warnings.push([
500
+ "multipart-headers",
501
+ "multipart headers are not supported: " +
502
+ m.headers.map((h) => h.toString()).join(", "),
503
+ ]);
504
+ }
505
+ if ("headerFiles" in m && m.headerFiles) {
506
+ warnings.push([
507
+ "multipart-headers",
508
+ "multipart header files are not supported: " +
509
+ m.headerFiles.map((h) => h.toString()).join(", "),
510
+ ]);
511
+ }
512
+ }
513
+
514
+ code += " curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime1);\n";
515
+
516
+ cleanup += " curl_mime_free(mime1);\n";
517
+ cleanup += " mime1 = NULL;\n";
518
+ } else if (request.data) {
519
+ code +=
520
+ " curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, " +
521
+ repr(request.data, imports) +
522
+ ");\n";
523
+ // this isn't correct if .data reads files
524
+ code +=
525
+ " curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)" +
526
+ request.data.length.toString() +
527
+ ");\n";
528
+ }
529
+ if (request.formEscape) {
530
+ code += " curl_easy_setopt(hnd, CURLOPT_MIME_OPTIONS, 1L);\n";
531
+ }
532
+
533
+ if (request.urls[0].auth) {
534
+ const curlAuth = AUTH_TO_VAR[request.authType];
535
+ code +=
536
+ " curl_easy_setopt(hnd, CURLOPT_HTTPAUTH, (long)" + curlAuth + ");\n";
537
+ }
538
+
539
+ const headerLines = [];
540
+ for (const [headerName, headerValue] of request.headers) {
541
+ const h = headerName.toLowerCase();
542
+ if (eq(h, "user-agent") || eq(h, "referer")) {
543
+ continue;
544
+ }
545
+ if (headerValue === null) {
546
+ headerLines.push(
547
+ " headers = curl_slist_append(headers, " +
548
+ repr(mergeWords(headerName, ":"), imports) +
549
+ ");\n",
550
+ );
551
+ } else if (eq(headerValue, "")) {
552
+ headerLines.push(
553
+ " headers = curl_slist_append(headers, " +
554
+ repr(mergeWords(headerName, ";"), imports) +
555
+ ");\n",
556
+ );
557
+ } else {
558
+ headerLines.push(
559
+ " headers = curl_slist_append(headers, " +
560
+ repr(mergeWords(headerName, ": ", headerValue), imports) +
561
+ ");\n",
562
+ );
563
+ }
564
+ }
565
+ if (headerLines.length) {
566
+ preamble += " struct curl_slist *headers;\n";
567
+
568
+ vars += " headers = NULL;\n";
569
+ vars += headerLines.join("");
570
+
571
+ code += " curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);\n";
572
+
573
+ cleanup += " curl_slist_free_all(headers);\n";
574
+ cleanup += " headers = NULL;\n";
575
+ }
576
+ const referer = request.headers.get("referer");
577
+ if (referer) {
578
+ code +=
579
+ " curl_easy_setopt(hnd, CURLOPT_REFERER, " +
580
+ repr(referer, imports) +
581
+ ");\n";
582
+ // TODO: only if passed with --referer and not -H
583
+ }
584
+ const userAgent = request.headers.get("user-agent");
585
+ if (userAgent) {
586
+ code +=
587
+ " curl_easy_setopt(hnd, CURLOPT_USERAGENT, " +
588
+ repr(userAgent, imports) +
589
+ ");\n";
590
+ } else if (userAgent === undefined) {
591
+ // TODO: needs to be kept up-to-date with VERSION in cli.ts
592
+ code += ' curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/8.2.1");\n';
593
+ }
594
+
595
+ if (request.followRedirects) {
596
+ code += " curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L);\n";
597
+ if (request.followRedirectsTrusted) {
598
+ code += " curl_easy_setopt(hnd, CURLOPT_UNRESTRICTED_AUTH, 1L);\n";
599
+ }
600
+ }
601
+
602
+ if (request.awsSigV4) {
603
+ const awsSig = repr(request.awsSigV4, imports);
604
+ code += " curl_easy_setopt(hnd, CURLOPT_AWS_SIGV4, " + awsSig + ");\n";
605
+ }
606
+
607
+ if (request.refererAuto) {
608
+ code += " curl_easy_setopt(hnd, CURLOPT_AUTOREFERER, 1L);\n";
609
+ }
610
+
611
+ if (request.proxyHeaders.length) {
612
+ // TODO: camelCase snake_case orjustoneword?
613
+ preamble += " struct curl_slist *proxy_headers;\n";
614
+
615
+ if (vars) {
616
+ vars += "\n";
617
+ }
618
+ vars += " proxy_headers = NULL;\n";
619
+ for (const [headerName, headerValue] of request.proxyHeaders) {
620
+ if (headerValue === null) {
621
+ vars +=
622
+ " proxy_headers = curl_slist_append(proxy_headers, " +
623
+ repr(mergeWords(headerName, ":"), imports) +
624
+ ");\n";
625
+ } else if (eq(headerValue, "")) {
626
+ vars +=
627
+ " proxy_headers = curl_slist_append(proxy_headers, " +
628
+ repr(mergeWords(headerName, ";"), imports) +
629
+ ");\n";
630
+ } else {
631
+ vars +=
632
+ " proxy_headers = curl_slist_append(proxy_headers, " +
633
+ repr(mergeWords(headerName, ": ", headerValue), imports) +
634
+ ");\n";
635
+ }
636
+ }
637
+
638
+ code += " curl_easy_setopt(hnd, CURLOPT_PROXYHEADER, proxy_headers);\n";
639
+ code +=
640
+ " curl_easy_setopt(hnd, CURLOPT_HEADEROPT, (long)CURLHEADER_SEPARATE);\n";
641
+
642
+ cleanup += " curl_slist_free_all(proxy_headers);\n";
643
+ cleanup += " proxy_headers = NULL;\n";
644
+ }
645
+
646
+ const maxRedirs = request.maxRedirects || new Word("50");
647
+ code +=
648
+ " curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, " +
649
+ atol(maxRedirs, imports) +
650
+ ");\n";
651
+
652
+ let httpVersion = "CURL_HTTP_VERSION_2TLS";
653
+ if (request.httpVersion) {
654
+ httpVersion = {
655
+ "1.0": "CURL_HTTP_VERSION_1_0",
656
+ "1.1": "CURL_HTTP_VERSION_1_1",
657
+ "2": "CURL_HTTP_VERSION_2_0",
658
+ "2-prior-knowledge": "CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE",
659
+ "3": "CURL_HTTP_VERSION_3",
660
+ "3-only": "CURL_HTTP_VERSION_3ONLY",
661
+ }[request.httpVersion];
662
+ }
663
+ code +=
664
+ " curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)" +
665
+ httpVersion +
666
+ ");\n";
667
+ if (request.http0_9) {
668
+ code += " curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);\n";
669
+ }
670
+
671
+ if (request.post301 || request.post302 || request.post303) {
672
+ const postRedir = [];
673
+ if (request.post301) {
674
+ postRedir.push("CURL_REDIR_POST_301");
675
+ }
676
+ if (request.post302) {
677
+ postRedir.push("CURL_REDIR_POST_302");
678
+ }
679
+ if (request.post303) {
680
+ postRedir.push("CURL_REDIR_POST_303");
681
+ }
682
+ code +=
683
+ " curl_easy_setopt(hnd, CURLOPT_POSTREDIR, " +
684
+ postRedir.join(" | ") +
685
+ ");\n";
686
+ }
687
+
688
+ if (request.compressed) {
689
+ code += ' curl_easy_setopt(hnd, CURLOPT_ACCEPT_ENCODING, "");\n';
690
+ }
691
+
692
+ if (request.transferEncoding) {
693
+ code += " curl_easy_setopt(hnd, CURLOPT_TRANSFER_ENCODING, 1L);\n";
694
+ }
695
+
696
+ if (request.speedLimit || request.speedTime) {
697
+ const speedLimit = atol(request.speedLimit || new Word("1"), imports);
698
+ const speedTime = atol(request.speedTime || new Word("30"), imports);
699
+ code +=
700
+ " curl_easy_setopt(hnd, CURLOPT_LOW_SPEED_LIMIT, " + speedLimit + ");\n";
701
+ code +=
702
+ " curl_easy_setopt(hnd, CURLOPT_LOW_SPEED_TIME, " + speedTime + ");\n";
703
+ }
704
+ if (request.limitRate) {
705
+ // TODO: parse
706
+ const limitRate = repr(request.limitRate, imports);
707
+ code +=
708
+ " curl_easy_setopt(hnd, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t)" +
709
+ limitRate +
710
+ ");\n";
711
+ code +=
712
+ " curl_easy_setopt(hnd, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t)" +
713
+ limitRate +
714
+ ");\n";
715
+ }
716
+
717
+ if (request.continueAt) {
718
+ if (!eq(request.continueAt, "-")) {
719
+ const continueAt = atoi(request.continueAt, imports);
720
+ code +=
721
+ " curl_easy_setopt(hnd, CURLOPT_RESUME_FROM_LARGE, (curl_off_t)" +
722
+ continueAt +
723
+ ");\n";
724
+ }
725
+ }
726
+
727
+ if (request.pass) {
728
+ const pass = repr(request.pass, imports);
729
+ // TODO: --cert can also set this
730
+ code += " curl_easy_setopt(hnd, CURLOPT_KEYPASSWD, " + pass + ");\n";
731
+ }
732
+ if (request.proxyPass) {
733
+ // TODO: --proxy-cert can also set this
734
+ const proxyPass = repr(request.proxyPass, imports);
735
+ code +=
736
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_KEYPASSWD, " + proxyPass + ");\n";
737
+ }
738
+
739
+ if (request.cacert) {
740
+ const cacert = repr(request.cacert, imports);
741
+ code += " curl_easy_setopt(hnd, CURLOPT_CAINFO, " + cacert + ");\n";
742
+ }
743
+ if (request.proxyCacert) {
744
+ const proxyCacert = repr(request.proxyCacert, imports);
745
+ code +=
746
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_CAINFO, " + proxyCacert + ");\n";
747
+ }
748
+
749
+ if (request.capath || request.proxyCapath) {
750
+ if (request.capath) {
751
+ const capath = repr(request.capath, imports);
752
+ code += " curl_easy_setopt(hnd, CURLOPT_CAPATH, " + capath + ");\n";
753
+ const proxyCapath = repr(request.proxyCapath || request.capath, imports);
754
+ code +=
755
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_CAPATH, " + proxyCapath + ");\n";
756
+ } else if (request.proxyCapath) {
757
+ // placate type checker
758
+ const proxyCapath = repr(request.proxyCapath, imports);
759
+ code +=
760
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_CAPATH, " + proxyCapath + ");\n";
761
+ }
762
+ }
763
+
764
+ if (request.crlfile || request.proxyCrlfile) {
765
+ if (request.crlfile) {
766
+ const crlfile = repr(request.crlfile, imports);
767
+ code += " curl_easy_setopt(hnd, CURLOPT_CRLFILE, " + crlfile + ");\n";
768
+ const proxyCrlfile = repr(
769
+ request.proxyCrlfile || request.crlfile,
770
+ imports,
771
+ );
772
+ code +=
773
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_CRLFILE, " +
774
+ proxyCrlfile +
775
+ ");\n";
776
+ } else if (request.proxyCrlfile) {
777
+ // placate type checker
778
+ const proxyCrlfile = repr(request.proxyCrlfile, imports);
779
+ code +=
780
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_CRLFILE, " +
781
+ proxyCrlfile +
782
+ ");\n";
783
+ }
784
+ }
785
+ if (request.pinnedpubkey) {
786
+ const pinnedpubkey = repr(request.pinnedpubkey, imports);
787
+ code +=
788
+ " curl_easy_setopt(hnd, CURLOPT_PINNEDPUBLICKEY, " +
789
+ pinnedpubkey +
790
+ ");\n";
791
+ }
792
+ // TODO: --proxy-pinnedpubkey ?
793
+ if (request.curves) {
794
+ const curves = repr(request.curves, imports);
795
+ code += " curl_easy_setopt(hnd, CURLOPT_SSL_EC_CURVES, " + curves + ");\n";
796
+ }
797
+ if (request.cert) {
798
+ const [cert, pass] = request.cert;
799
+ if (pass) {
800
+ code +=
801
+ " curl_easy_setopt(hnd, CURLOPT_KEYPASSWD, " +
802
+ repr(pass, imports) +
803
+ ");\n";
804
+ }
805
+ code +=
806
+ " curl_easy_setopt(hnd, CURLOPT_SSLCERT, " +
807
+ repr(cert, imports) +
808
+ ");\n";
809
+ }
810
+ if (request.proxyCert) {
811
+ // TODO: split
812
+ const proxyCert = repr(request.proxyCert, imports);
813
+ code +=
814
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSLCERT, " + proxyCert + ");\n";
815
+ }
816
+ if (request.certType) {
817
+ const certType = repr(request.certType, imports);
818
+ code += " curl_easy_setopt(hnd, CURLOPT_SSLCERTTYPE, " + certType + ");\n";
819
+ }
820
+ if (request.proxyCertType) {
821
+ const proxyCertType = repr(request.proxyCertType, imports);
822
+ code +=
823
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSLCERTTYPE, " +
824
+ proxyCertType +
825
+ ");\n";
826
+ }
827
+ if (request.key) {
828
+ const key = repr(request.key, imports);
829
+ code += " curl_easy_setopt(hnd, CURLOPT_SSLKEY, " + key + ");\n";
830
+ }
831
+ if (request.proxyKey) {
832
+ const proxyKey = repr(request.proxyKey, imports);
833
+ code +=
834
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSLKEY, " + proxyKey + ");\n";
835
+ }
836
+ if (request.keyType) {
837
+ const keyType = repr(request.keyType, imports);
838
+ code += " curl_easy_setopt(hnd, CURLOPT_SSLKEYTYPE, " + keyType + ");\n";
839
+ }
840
+ if (request.proxyKeyType) {
841
+ const proxyKeyType = repr(request.proxyKeyType, imports);
842
+ code +=
843
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSLKEYTYPE, " +
844
+ proxyKeyType +
845
+ ");\n";
846
+ }
847
+
848
+ if (request.insecure) {
849
+ code += " curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);\n";
850
+ code += " curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);\n";
851
+ }
852
+ if (request.proxyInsecure) {
853
+ code += " curl_easy_setopt(hnd, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);\n";
854
+ code += " curl_easy_setopt(hnd, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);\n";
855
+ }
856
+ if (request.certStatus) {
857
+ code += " curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYSTATUS, 1L);\n";
858
+ }
859
+ if (request.dohCertStatus) {
860
+ code += " curl_easy_setopt(hnd, CURLOPT_DOH_SSL_VERIFYSTATUS, 1L);\n";
861
+ }
862
+
863
+ let tlsVersion = null;
864
+ if (request.tlsVersion) {
865
+ tlsVersion = {
866
+ "1": "CURL_SSLVERSION_TLSv1",
867
+ "1.0": "CURL_SSLVERSION_TLSv1_0",
868
+ "1.1": "CURL_SSLVERSION_TLSv1_1",
869
+ "1.2": "CURL_SSLVERSION_TLSv1_2",
870
+ "1.3": "CURL_SSLVERSION_TLSv1_3",
871
+ }[request.tlsVersion];
872
+ }
873
+ let tlsMax = null;
874
+ if (request.tlsMax) {
875
+ if (request.tlsMax.isString()) {
876
+ const tlsMaxVal = request.tlsMax.toString();
877
+ switch (tlsMaxVal) {
878
+ case "1.0":
879
+ tlsMax = "CURL_SSLVERSION_MAX_TLSv1_0";
880
+ break;
881
+ case "1.1":
882
+ tlsMax = "CURL_SSLVERSION_MAX_TLSv1_1";
883
+ break;
884
+ case "1.2":
885
+ tlsMax = "CURL_SSLVERSION_MAX_TLSv1_2";
886
+ break;
887
+ case "1.3":
888
+ tlsMax = "CURL_SSLVERSION_MAX_TLSv1_3";
889
+ break;
890
+ case "default":
891
+ tlsMax = "CURL_SSLVERSION_MAX_DEFAULT";
892
+ break;
893
+ default:
894
+ warnings.push([
895
+ "tls-max",
896
+ "unknown value for --tls-max: " + JSON.stringify(tlsMaxVal),
897
+ ]);
898
+ }
899
+ } else {
900
+ warnings.push([
901
+ "tls-max",
902
+ "unparseable value for --tls-max: " +
903
+ JSON.stringify(request.tlsMax.toString()),
904
+ ]);
905
+ }
906
+ }
907
+ if (tlsVersion || tlsMax) {
908
+ if (!tlsVersion) {
909
+ // not really necessary since it's 0
910
+ tlsVersion = "CURL_SSLVERSION_DEFAULT";
911
+ }
912
+ code += " curl_easy_setopt(hnd, CURLOPT_SSLVERSION, (long)";
913
+ if (tlsMax) {
914
+ code += "(" + tlsVersion + " | " + tlsMax + ")";
915
+ } else {
916
+ code += tlsVersion;
917
+ }
918
+ code += ");\n";
919
+ }
920
+ if (request.proxyTlsv1) {
921
+ code +=
922
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSLVERSION, (long)CURL_SSLVERSION_TLSv1);\n";
923
+ }
924
+ if (
925
+ request.sslAllowBeast ||
926
+ request.sslNoRevoke ||
927
+ request.sslRevokeBestEffort ||
928
+ request.caNative ||
929
+ request.sslAutoClientCert
930
+ ) {
931
+ const sslOptions = [];
932
+ if (request.sslAllowBeast) {
933
+ sslOptions.push("CURLSSLOPT_ALLOW_BEAST");
934
+ }
935
+ if (request.sslNoRevoke) {
936
+ sslOptions.push("CURLSSLOPT_NO_REVOKE");
937
+ }
938
+ if (request.sslRevokeBestEffort) {
939
+ sslOptions.push("CURLSSLOPT_REVOKE_BEST_EFFORT");
940
+ }
941
+ if (request.caNative) {
942
+ sslOptions.push("CURLSSLOPT_NATIVE_CA");
943
+ }
944
+ if (request.sslAutoClientCert) {
945
+ sslOptions.push("CURLSSLOPT_AUTO_CLIENT_CERT");
946
+ }
947
+ code +=
948
+ " curl_easy_setopt(hnd, CURLOPT_SSL_OPTIONS, (long)" +
949
+ (sslOptions.length > 1 ? "(" : "") +
950
+ sslOptions.join(" | ") +
951
+ (sslOptions.length > 1 ? ")" : "") +
952
+ ");\n";
953
+ }
954
+
955
+ if (
956
+ request.proxySslAllowBeast ||
957
+ request.proxyCaNative ||
958
+ request.proxySslAutoClientCert
959
+ ) {
960
+ const sslOptions = [];
961
+ if (request.proxySslAllowBeast) {
962
+ sslOptions.push("CURLSSLOPT_ALLOW_BEAST");
963
+ }
964
+ if (request.proxyCaNative) {
965
+ sslOptions.push("CURLSSLOPT_NATIVE_CA");
966
+ }
967
+ if (request.proxySslAutoClientCert) {
968
+ sslOptions.push("CURLSSLOPT_AUTO_CLIENT_CERT");
969
+ }
970
+ code +=
971
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSL_OPTIONS, (long)" +
972
+ sslOptions.join(" | (long)") +
973
+ ");\n";
974
+ }
975
+
976
+ if (request.pathAsIs) {
977
+ code += " curl_easy_setopt(hnd, CURLOPT_PATH_AS_IS, 1L);\n";
978
+ }
979
+
980
+ if (request.remoteTime) {
981
+ code += " curl_easy_setopt(hnd, CURLOPT_FILETIME, 1L);\n";
982
+ }
983
+
984
+ if (request.crlf) {
985
+ code += " curl_easy_setopt(hnd, CURLOPT_CRLF, 1L);\n";
986
+ }
987
+
988
+ if (request.cookieFiles) {
989
+ for (const cookieFile of request.cookieFiles) {
990
+ // TODO: why can curl set this more than once?
991
+ const cookieFile_ = repr(cookieFile, imports);
992
+ code +=
993
+ " curl_easy_setopt(hnd, CURLOPT_COOKIEFILE, " + cookieFile_ + ");\n";
994
+ }
995
+ }
996
+ if (request.cookieJar) {
997
+ const cookieJar = repr(request.cookieJar, imports);
998
+ code += " curl_easy_setopt(hnd, CURLOPT_COOKIEJAR, " + cookieJar + ");\n";
999
+ }
1000
+ if (request.junkSessionCookies) {
1001
+ code += " curl_easy_setopt(hnd, CURLOPT_COOKIESESSION, 1L);\n";
1002
+ }
1003
+
1004
+ // TODO: this is more complicated.
1005
+ // --head just sets CURLOPT_NOBODY and CURLOPT_FILETIME
1006
+ // --upload-file just sets CURLOPT_UPLOAD and CURLOPT_INFILESIZE_LARGE
1007
+ let expectedMethod = "GET";
1008
+ if (request.data || request.multipartUploads) {
1009
+ expectedMethod = "POST";
1010
+ }
1011
+ if (!eq(request.urls[0].method, expectedMethod)) {
1012
+ code +=
1013
+ " curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, " +
1014
+ repr(request.urls[0].method, imports) +
1015
+ ");\n";
1016
+ }
1017
+
1018
+ if (request.interface) {
1019
+ const interface_ = repr(request.interface, imports);
1020
+ code += " curl_easy_setopt(hnd, CURLOPT_INTERFACE, " + interface_ + ");\n";
1021
+ }
1022
+
1023
+ if (request.krb) {
1024
+ const krb = repr(request.krb, imports);
1025
+ code += " curl_easy_setopt(hnd, CURLOPT_KRBLEVEL, " + krb + ");\n";
1026
+ }
1027
+
1028
+ if (request.connectTimeout) {
1029
+ code +=
1030
+ " curl_easy_setopt(hnd, CURLOPT_CONNECTTIMEOUT_MS, " +
1031
+ atof1000(request.connectTimeout, imports) +
1032
+ ");\n";
1033
+ }
1034
+
1035
+ if (request.dohUrl) {
1036
+ const dohUrl = repr(request.dohUrl, imports);
1037
+ code += " curl_easy_setopt(hnd, CURLOPT_DOH_URL, " + dohUrl + ");\n";
1038
+ }
1039
+
1040
+ if (request.ciphers) {
1041
+ const ciphers = repr(request.ciphers, imports);
1042
+ code +=
1043
+ " curl_easy_setopt(hnd, CURLOPT_SSL_CIPHER_LIST, " + ciphers + ");\n";
1044
+ }
1045
+ if (request.proxyCiphers) {
1046
+ const proxyCiphers = repr(request.proxyCiphers, imports);
1047
+ code +=
1048
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SSL_CIPHER_LIST, " +
1049
+ proxyCiphers +
1050
+ ");\n";
1051
+ }
1052
+ if (request.tls13Ciphers) {
1053
+ const tls13Ciphers = repr(request.tls13Ciphers, imports);
1054
+ code +=
1055
+ " curl_easy_setopt(hnd, CURLOPT_TLS13_CIPHERS, " + tls13Ciphers + ");\n";
1056
+ }
1057
+ if (request.proxyTls13Ciphers) {
1058
+ const proxyTls13Ciphers = repr(request.proxyTls13Ciphers, imports);
1059
+ code +=
1060
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_TLS13_CIPHERS, " +
1061
+ proxyTls13Ciphers +
1062
+ ");\n";
1063
+ }
1064
+
1065
+ if (request.verbose) {
1066
+ code += " curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);\n";
1067
+ }
1068
+ if (request.maxFilesize) {
1069
+ // TODO: parse
1070
+ const maxFilesize = atol(request.maxFilesize, imports);
1071
+ code +=
1072
+ " curl_easy_setopt(hnd, CURLOPT_MAXFILESIZE_LARGE, (curl_off_t)" +
1073
+ maxFilesize +
1074
+ ");\n";
1075
+ }
1076
+
1077
+ // TODO: these should be mutually exclusive
1078
+ if (request.ipv6) {
1079
+ code += " curl_easy_setopt(hnd, CURLOPT_IPRESOLVE, 2L);\n";
1080
+ } else if (request.ipv4) {
1081
+ code += " curl_easy_setopt(hnd, CURLOPT_IPRESOLVE, 1L);\n";
1082
+ }
1083
+
1084
+ if (request.sslReqd || request.ssl) {
1085
+ if (request.sslReqd) {
1086
+ code +=
1087
+ " curl_easy_setopt(hnd, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);\n";
1088
+ } else if (request.ssl) {
1089
+ code +=
1090
+ " curl_easy_setopt(hnd, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY);\n";
1091
+ }
1092
+ }
1093
+
1094
+ if (request.socks5GssapiNec) {
1095
+ code += " curl_easy_setopt(hnd, CURLOPT_SOCKS5_GSSAPI_NEC, 1L);\n";
1096
+ }
1097
+
1098
+ if (request.socks5Basic) {
1099
+ code +=
1100
+ " curl_easy_setopt(hnd, CURLOPT_SOCKS5_AUTH, (long)CURLAUTH_BASIC);\n";
1101
+ } else if (request.socks5Gssapi) {
1102
+ code +=
1103
+ " curl_easy_setopt(hnd, CURLOPT_SOCKS5_AUTH, (long)CURLAUTH_GSSNEGOTIATE);\n";
1104
+ }
1105
+
1106
+ if (request.socks5GssapiService) {
1107
+ const socks5GssapiService = repr(request.socks5GssapiService, imports);
1108
+ code +=
1109
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SERVICE_NAME, " +
1110
+ socks5GssapiService +
1111
+ ");\n";
1112
+ }
1113
+
1114
+ if (request.serviceName) {
1115
+ const serviceName = repr(request.serviceName, imports);
1116
+ code +=
1117
+ " curl_easy_setopt(hnd, CURLOPT_SERVICE_NAME, " + serviceName + ");\n";
1118
+ }
1119
+ if (request.proxyServiceName) {
1120
+ const proxyServiceName = repr(request.proxyServiceName, imports);
1121
+ code +=
1122
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_SERVICE_NAME, " +
1123
+ proxyServiceName +
1124
+ ");\n";
1125
+ }
1126
+
1127
+ // TODO: check
1128
+ if (request.ignoreContentLength) {
1129
+ code += " curl_easy_setopt(hnd, CURLOPT_IGNORE_CONTENT_LENGTH, 1L);\n";
1130
+ }
1131
+
1132
+ if (request.ftpSkipPasvIp !== false) {
1133
+ code += " curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);\n";
1134
+ }
1135
+ if (request.keepAlive !== false) {
1136
+ code += " curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);\n";
1137
+ if (request.keepAliveTime) {
1138
+ const keepAliveTime = atol(request.keepAliveTime, imports);
1139
+ code +=
1140
+ " curl_easy_setopt(hnd, CURLOPT_TCP_KEEPIDLE, " +
1141
+ keepAliveTime +
1142
+ ");\n";
1143
+ code +=
1144
+ " curl_easy_setopt(hnd, CURLOPT_TCP_KEEPINTVL, " +
1145
+ keepAliveTime +
1146
+ ");\n";
1147
+ }
1148
+ }
1149
+
1150
+ if (request.proto) {
1151
+ // TODO: parse
1152
+ const proto = repr(request.proto, imports);
1153
+ code += " curl_easy_setopt(hnd, CURLOPT_PROTOCOLS_STR, " + proto + ");\n";
1154
+ }
1155
+ if (request.protoRedir) {
1156
+ // TODO: parse
1157
+ const protoRedir = repr(request.protoRedir, imports);
1158
+ code +=
1159
+ " curl_easy_setopt(hnd, CURLOPT_REDIR_PROTOCOLS_STR, " +
1160
+ protoRedir +
1161
+ ");\n";
1162
+ }
1163
+
1164
+ if (request.resolve) {
1165
+ preamble += " struct curl_slist *resolve;\n";
1166
+
1167
+ if (vars) {
1168
+ vars += "\n";
1169
+ }
1170
+ vars += " resolve = NULL;\n";
1171
+ for (const line of request.resolve) {
1172
+ vars +=
1173
+ " resolve = curl_slist_append(resolve, " +
1174
+ repr(line, imports) +
1175
+ ");\n";
1176
+ }
1177
+
1178
+ code += " curl_easy_setopt(hnd, CURLOPT_RESOLVE, resolve);\n";
1179
+
1180
+ cleanup += " curl_slist_free_all(resolve);\n";
1181
+ cleanup += " resolve = NULL;\n";
1182
+ }
1183
+ if (request.connectTo) {
1184
+ // TODO: camelCase snake_case orjustoneword?
1185
+ preamble += " struct curl_slist *connect_to;\n";
1186
+
1187
+ if (vars) {
1188
+ vars += "\n";
1189
+ }
1190
+ vars += " connect_to = NULL;\n";
1191
+ for (const line of request.connectTo) {
1192
+ vars +=
1193
+ " connect_to = curl_slist_append(connect_to, " +
1194
+ repr(line, imports) +
1195
+ ");\n";
1196
+ }
1197
+
1198
+ code += " curl_easy_setopt(hnd, CURLOPT_CONNECT_TO, connect_to);\n";
1199
+
1200
+ cleanup += " curl_slist_free_all(connect_to);\n";
1201
+ cleanup += " connect_to = NULL;\n";
1202
+ }
1203
+
1204
+ if (request.tlsuser) {
1205
+ const tlsuser = repr(request.tlsuser, imports);
1206
+ code +=
1207
+ " curl_easy_setopt(hnd, CURLOPT_TLSAUTH_USERNAME, " + tlsuser + ");\n";
1208
+ }
1209
+ if (request.tlspassword) {
1210
+ const tlspassword = repr(request.tlspassword, imports);
1211
+ code +=
1212
+ " curl_easy_setopt(hnd, CURLOPT_TLSAUTH_PASSWORD, " +
1213
+ tlspassword +
1214
+ ");\n";
1215
+ }
1216
+ if (request.tlsauthtype) {
1217
+ const tlsauthtype = repr(request.tlsauthtype, imports);
1218
+ code +=
1219
+ " curl_easy_setopt(hnd, CURLOPT_TLSAUTH_TYPE, " + tlsauthtype + ");\n";
1220
+ }
1221
+
1222
+ if (request.proxyTlsuser) {
1223
+ const proxyTlsuser = repr(request.proxyTlsuser, imports);
1224
+ code +=
1225
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_TLSAUTH_USERNAME, " +
1226
+ proxyTlsuser +
1227
+ ");\n";
1228
+ }
1229
+ if (request.proxyTlspassword) {
1230
+ const proxyTlspassword = repr(request.proxyTlspassword, imports);
1231
+ code +=
1232
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_TLSAUTH_PASSWORD, " +
1233
+ proxyTlspassword +
1234
+ ");\n";
1235
+ }
1236
+ if (request.proxyTlsauthtype) {
1237
+ const proxyTlsauthtype = repr(request.proxyTlsauthtype, imports);
1238
+ code +=
1239
+ " curl_easy_setopt(hnd, CURLOPT_PROXY_TLSAUTH_TYPE, " +
1240
+ proxyTlsauthtype +
1241
+ ");\n";
1242
+ }
1243
+
1244
+ if (request.delegation) {
1245
+ if (eq(request.delegation, "always")) {
1246
+ code += " curl_easy_setopt(hnd, CURLOPT_GSSAPI_DELEGATION, 2L);\n";
1247
+ } else if (eq(request.delegation, "policy")) {
1248
+ code += " curl_easy_setopt(hnd, CURLOPT_GSSAPI_DELEGATION, 1L);\n";
1249
+ }
1250
+ }
1251
+
1252
+ if (request.saslAuthzid) {
1253
+ const zid = repr(request.saslAuthzid, imports);
1254
+ code += " curl_easy_setopt(hnd, CURLOPT_SASL_AUTHZID, " + zid + ");\n";
1255
+ }
1256
+ if (request.saslIr) {
1257
+ code += " curl_easy_setopt(hnd, CURLOPT_SASL_IR, 1L);\n";
1258
+ }
1259
+
1260
+ if (request.alpn === false) {
1261
+ code += " curl_easy_setopt(hnd, CURLOPT_SSL_ENABLE_ALPN, 0L);\n";
1262
+ }
1263
+
1264
+ if (request.unixSocket) {
1265
+ const socket = repr(request.unixSocket, imports);
1266
+ code +=
1267
+ " curl_easy_setopt(hnd, CURLOPT_UNIX_SOCKET_PATH, " + socket + ");\n";
1268
+ }
1269
+ if (request.abstractUnixSocket) {
1270
+ const socket = repr(request.abstractUnixSocket, imports);
1271
+ code +=
1272
+ " curl_easy_setopt(hnd, CURLOPT_ABSTRACT_UNIX_SOCKET, " +
1273
+ socket +
1274
+ ");\n";
1275
+ }
1276
+
1277
+ if (request.protoDefault) {
1278
+ const protoDefault = repr(request.protoDefault, imports);
1279
+ code +=
1280
+ " curl_easy_setopt(hnd, CURLOPT_DEFAULT_PROTOCOL, " +
1281
+ protoDefault +
1282
+ ");\n";
1283
+ }
1284
+
1285
+ if (request.expect100Timeout) {
1286
+ code +=
1287
+ " curl_easy_setopt(hnd, CURLOPT_EXPECT_100_TIMEOUT_MS, " +
1288
+ atof1000(request.expect100Timeout, imports) +
1289
+ ");\n";
1290
+ }
1291
+ if (request.happyEyeballsTimeoutMs) {
1292
+ code +=
1293
+ " curl_easy_setopt(hnd, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, " +
1294
+ atol(request.happyEyeballsTimeoutMs, imports) +
1295
+ ");\n";
1296
+ }
1297
+
1298
+ if (request.haproxyClientIp) {
1299
+ const haproxyClientIp = repr(request.haproxyClientIp, imports);
1300
+ code +=
1301
+ " curl_easy_setopt(hnd, CURLOPT_HAPROXY_CLIENT_IP, " +
1302
+ haproxyClientIp +
1303
+ ");\n";
1304
+ }
1305
+ if (request.haproxyProtocol) {
1306
+ code += " curl_easy_setopt(hnd, CURLOPT_HAPROXYPROTOCOL, 1L);\n";
1307
+ }
1308
+
1309
+ if (request.disallowUsernameInUrl) {
1310
+ code += " curl_easy_setopt(hnd, CURLOPT_DISALLOW_USERNAME_IN_URL, 1L);\n";
1311
+ }
1312
+
1313
+ if (request.altSvc) {
1314
+ const altSvc = repr(request.altSvc, imports);
1315
+ code += " curl_easy_setopt(hnd, CURLOPT_ALTSVC, " + altSvc + ");\n";
1316
+ }
1317
+
1318
+ if (request.hsts) {
1319
+ // TODO: warn that files aren't read?
1320
+ const hsts = repr(request.hsts[request.hsts.length - 1], imports);
1321
+ code += " curl_easy_setopt(hnd, CURLOPT_HSTS, " + hsts + ");\n";
1322
+ }
1323
+
1324
+ code += "\n";
1325
+ code += " ret = curl_easy_perform(hnd);\n";
1326
+
1327
+ let end = "";
1328
+ end += " return (int)ret;\n";
1329
+ end += "}\n";
1330
+
1331
+ return (
1332
+ preamble +
1333
+ (vars ? "\n" + vars : "") +
1334
+ "\n" +
1335
+ code +
1336
+ "\n" +
1337
+ cleanup +
1338
+ "\n" +
1339
+ end
1340
+ );
1341
+ }
1342
+
1343
+ export function printImports(imps: Set<string>): string {
1344
+ let s = "";
1345
+ for (const imp of Array.from(imps).sort()) {
1346
+ s += "#include <" + imp + ">\n";
1347
+ }
1348
+ return s;
1349
+ }
1350
+
1351
+ export function _toC(requests: Request[], warnings: Warnings = []): string {
1352
+ const imports = new Set<string>(["curl/curl.h"]);
1353
+
1354
+ const request = getFirst(requests, warnings, { cookieFiles: true });
1355
+ const code = requestToC(request, warnings, imports);
1356
+
1357
+ return printImports(imports) + "\n" + code;
1358
+ }
1359
+
1360
+ export function toCWarn(
1361
+ curlCommand: string | string[],
1362
+ warnings: Warnings = [],
1363
+ ): [string, Warnings] {
1364
+ const requests = parse(curlCommand, supportedArgs, warnings);
1365
+ const c = _toC(requests, warnings);
1366
+ return [c, warnings];
1367
+ }
1368
+
1369
+ export function toC(curlCommand: string | string[]): string {
1370
+ return toCWarn(curlCommand)[0];
1371
+ }