@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,263 @@
1
+ import { Word, joinWords } from "../../shell/Word.js";
2
+ import type { Request, Warnings } from "../../parse.js";
3
+
4
+ import {
5
+ reprStr,
6
+ repr,
7
+ setVariableValue,
8
+ callFunction,
9
+ addCellArray,
10
+ structify,
11
+ containsBody,
12
+ prepareQueryString,
13
+ prepareCookies,
14
+ cookieString,
15
+ paramsString,
16
+ } from "./common.js";
17
+
18
+ function isSupportedByWebServices(request: Request): boolean {
19
+ return (
20
+ ["get", "post", "put", "delete", "patch"].includes(
21
+ request.urls[0].method.toLowerCase().toString(),
22
+ ) &&
23
+ !request.multipartUploads &&
24
+ !request.insecure
25
+ );
26
+ }
27
+
28
+ interface Options {
29
+ RequestMethod?: Word;
30
+
31
+ Username?: Word;
32
+ Password?: Word;
33
+
34
+ UserAgent?: Word;
35
+ MediaType?: Word;
36
+ ContentType?: string;
37
+ HeaderFields?: string;
38
+ }
39
+
40
+ function setHeader(
41
+ headers: [Word, Word][],
42
+ header: Word,
43
+ value: Word,
44
+ lowercase: boolean,
45
+ ) {
46
+ headers.push([lowercase ? header.toLowerCase() : header, value]);
47
+ }
48
+
49
+ function parseWebOptions(request: Request): Options {
50
+ const options: Options = {};
51
+
52
+ // MATLAB uses GET in `webread` and POST in `webwrite` by default
53
+ // thus, it is necessary to set the method for other requests
54
+ const method = request.urls[0].method.toLowerCase().toString();
55
+ if (method !== "get" && method !== "post") {
56
+ options.RequestMethod = request.urls[0].method.toLowerCase();
57
+ }
58
+
59
+ const headers: [Word, Word][] = [];
60
+ const preformattedHeaders: string[] = [];
61
+ if (request.urls[0].auth) {
62
+ const [username, password] = request.urls[0].auth;
63
+ if (username.length) {
64
+ options.Username = username;
65
+ options.Password = password;
66
+ } else {
67
+ const authHeader = `['Basic ' matlab.net.base64encode(${repr(
68
+ joinWords(request.urls[0].auth, ":"),
69
+ )})]`;
70
+ setHeader(
71
+ headers,
72
+ new Word("Authorization"),
73
+ new Word(authHeader),
74
+ request.headers.lowercase,
75
+ );
76
+ preformattedHeaders.push("authorization");
77
+ }
78
+ }
79
+
80
+ if (request.headers.length) {
81
+ for (const [header, value] of request.headers) {
82
+ if (value === null) {
83
+ continue;
84
+ }
85
+ // Doing this case insensitively probably makes MATLAB send title-cased headers
86
+ switch (header.toLowerCase().toString()) {
87
+ case "user-agent":
88
+ options.UserAgent = value;
89
+ break;
90
+ case "content-type":
91
+ options.MediaType = value;
92
+ break;
93
+ case "cookie":
94
+ if (request.cookies) {
95
+ setHeader(
96
+ headers,
97
+ new Word("Cookie"),
98
+ new Word(cookieString),
99
+ request.headers.lowercase,
100
+ );
101
+ preformattedHeaders.push("cookie");
102
+ } else {
103
+ setHeader(headers, header, value, request.headers.lowercase);
104
+ }
105
+ break;
106
+ case "accept":
107
+ switch (value.toLowerCase().toString()) {
108
+ case "application/json":
109
+ options.ContentType = "json";
110
+ break;
111
+ case "text/csv":
112
+ options.ContentType = "table";
113
+ break;
114
+ case "text/plain":
115
+ case "text/html":
116
+ case "application/javascript":
117
+ case "application/x-javascript":
118
+ case "application/x-www-form-urlencoded":
119
+ options.ContentType = "text";
120
+ break;
121
+ case "text/xml":
122
+ case "application/xml":
123
+ options.ContentType = "xmldom";
124
+ break;
125
+ case "application/octet-stream":
126
+ options.ContentType = "binary";
127
+ break;
128
+ default:
129
+ if (value.startsWith("image/")) {
130
+ options.ContentType = "image";
131
+ } else if (value.startsWith("audio/")) {
132
+ options.ContentType = "audio";
133
+ } else {
134
+ setHeader(headers, header, value, request.headers.lowercase);
135
+ }
136
+ }
137
+ break;
138
+ default:
139
+ setHeader(headers, header, value, request.headers.lowercase);
140
+ }
141
+ }
142
+ }
143
+
144
+ if (headers.length > 0) {
145
+ // If key is on the same line as 'weboptions', there is only one parameter
146
+ // otherwise keys are indented by one level in the next line.
147
+ // An extra indentation level is given to the values's new lines in cell array
148
+ const indentLevel = 1 + (Object.keys(options).length === 0 ? 0 : 1);
149
+ options.HeaderFields = addCellArray(
150
+ headers,
151
+ preformattedHeaders,
152
+ indentLevel,
153
+ );
154
+ }
155
+
156
+ return options;
157
+ }
158
+
159
+ function prepareOptions(request: Request, options: Options): string[] {
160
+ const lines: string[] = [];
161
+ if (Object.keys(options).length === 0) {
162
+ return lines;
163
+ }
164
+ const pairValues = addCellArray(
165
+ Object.entries(options),
166
+ ["headerfields"],
167
+ 1,
168
+ true,
169
+ );
170
+ lines.push(callFunction("options", "weboptions", pairValues));
171
+
172
+ return lines;
173
+ }
174
+
175
+ function prepareBasicURI(request: Request): string[] {
176
+ const response: string[] = [];
177
+ if (request.urls[0].queryList) {
178
+ response.push(
179
+ setVariableValue("baseURI", repr(request.urls[0].urlWithoutQueryList)),
180
+ );
181
+ response.push(setVariableValue("uri", `[baseURI '?' ${paramsString}]`));
182
+ } else {
183
+ response.push(setVariableValue("uri", repr(request.urls[0].url)));
184
+ }
185
+ return response;
186
+ }
187
+
188
+ function prepareBasicData(request: Request): string | string[] {
189
+ if (request.data && request.data.length === 0) {
190
+ return setVariableValue("body", repr(new Word()));
191
+ }
192
+ if (!request.data) {
193
+ return [];
194
+ }
195
+ let response: string | string[] = [];
196
+ if (request.data.charAt(0) === "@") {
197
+ response.push(
198
+ callFunction("body", "fileread", repr(request.data.slice(1))),
199
+ );
200
+
201
+ if (!request.isDataBinary) {
202
+ response.push(setVariableValue("body(body==13 | body==10)", "[]"));
203
+ }
204
+ } else if (request.data.isString()) {
205
+ // if the data is in JSON, store it as struct in MATLAB
206
+ // otherwise just keep it as a char vector
207
+ try {
208
+ const jsonData = JSON.parse(request.data?.toString());
209
+ if (typeof jsonData === "object") {
210
+ let jsonText = structify(jsonData);
211
+ if (!jsonText.startsWith("struct")) jsonText = reprStr(jsonText);
212
+ response = setVariableValue("body", jsonText);
213
+ } else {
214
+ response = setVariableValue("body", repr(request.data));
215
+ }
216
+ } catch (e) {
217
+ response = setVariableValue("body", repr(request.data));
218
+ }
219
+ }
220
+ return response;
221
+ }
222
+
223
+ function prepareWebCall(request: Request, options: Options): string[] {
224
+ const lines: string[] = [];
225
+ const webFunction = containsBody(request) ? "webwrite" : "webread";
226
+
227
+ const params = ["uri"];
228
+ if (containsBody(request)) {
229
+ params.push("body");
230
+ }
231
+ if (Object.keys(options).length > 0) {
232
+ params.push("options");
233
+ }
234
+ lines.push(callFunction("response", webFunction, params));
235
+
236
+ return lines;
237
+ }
238
+
239
+ export function toWebServices(
240
+ request: Request,
241
+ warnings: Warnings,
242
+ ): [(string | string[] | null)[], Warnings] {
243
+ let lines: (string | string[] | null)[] = [
244
+ "%% Web Access using Data Import and Export API",
245
+ ];
246
+
247
+ if (!isSupportedByWebServices(request)) {
248
+ lines.push("% This is not possible with the webread/webwrite API");
249
+ return [lines, warnings];
250
+ }
251
+
252
+ const options = parseWebOptions(request);
253
+ lines = lines.concat([
254
+ prepareQueryString(request),
255
+ prepareCookies(request),
256
+ prepareBasicURI(request),
257
+ prepareBasicData(request),
258
+ prepareOptions(request, options),
259
+ prepareWebCall(request, options),
260
+ ]);
261
+
262
+ return [lines, warnings];
263
+ }
@@ -0,0 +1,297 @@
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
+ import type { DataParam } from "../Request.js";
5
+
6
+ export const supportedArgs = new Set([
7
+ ...COMMON_SUPPORTED_ARGS,
8
+ // TODO
9
+ // "form",
10
+ // "form-string",
11
+ "max-time",
12
+ ]);
13
+
14
+ // Presumably the same as C strings
15
+ // https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences
16
+ const regexEscape = /"|\\|\p{C}|[^ \P{Z}]/gu;
17
+ export function reprStr(s: string): string {
18
+ return (
19
+ '@"' +
20
+ s.replace(regexEscape, (c: string) => {
21
+ switch (c) {
22
+ case "\x07":
23
+ return "\\a";
24
+ case "\b":
25
+ return "\\b";
26
+ case "\f":
27
+ return "\\f";
28
+ case "\n":
29
+ return "\\n";
30
+ case "\r":
31
+ return "\\r";
32
+ case "\t":
33
+ return "\\t";
34
+ case "\v":
35
+ return "\\v";
36
+ case "\\":
37
+ return "\\\\";
38
+ case '"':
39
+ return '\\"';
40
+ }
41
+ const hex = (c.codePointAt(0) as number).toString(16);
42
+ if (hex.length <= 2) {
43
+ return "\\x" + hex.padStart(2, "0");
44
+ }
45
+ if (hex.length <= 4) {
46
+ return "\\u" + hex.padStart(4, "0");
47
+ }
48
+ return "\\U" + hex.padStart(8, "0");
49
+ }) +
50
+ '"'
51
+ );
52
+ }
53
+
54
+ export function repr(w: Word): string {
55
+ const args: string[] = [];
56
+ for (const t of w.tokens) {
57
+ if (typeof t === "string") {
58
+ args.push(reprStr(t));
59
+ } else if (t.type === "variable") {
60
+ // TODO: turns into "(null)" if variable doesn't exist
61
+ args.push(
62
+ "[[[NSProcessInfo processInfo] environment] objectForKey:" +
63
+ reprStr(t.value) +
64
+ "]",
65
+ );
66
+ } else if (t.type === "command") {
67
+ // TODO: doesn't return the output
68
+ args.push("system(" + reprStr(t.value) + ")");
69
+ }
70
+ }
71
+ if (args.length === 1) {
72
+ return args[0];
73
+ }
74
+ // This is how you concatenate strings in Objective-C.
75
+ return (
76
+ '[NSString stringWithFormat:@"' +
77
+ "%@".repeat(args.length) +
78
+ '", ' +
79
+ args.join(", ") +
80
+ "]"
81
+ );
82
+ }
83
+
84
+ const reservedHeaders = [
85
+ "Content-Length",
86
+ "Authorization",
87
+ "Connection",
88
+ "Host",
89
+ "Proxy-Authenticate",
90
+ "Proxy-Authorization",
91
+ "WWW-Authenticate",
92
+ ].map((h) => h.toLowerCase());
93
+
94
+ export function _toObjectiveC(
95
+ requests: Request[],
96
+ warnings: Warnings = [],
97
+ ): string {
98
+ const request = getFirst(requests, warnings, { dataReadsFile: true });
99
+ let code = "";
100
+ code += "#import <Foundation/Foundation.h>\n";
101
+ code += "\n";
102
+ code +=
103
+ "NSURL *url = [NSURL URLWithString:" + repr(request.urls[0].url) + "];\n";
104
+
105
+ if (request.urls[0].auth) {
106
+ const [user, password] = request.urls[0].auth;
107
+
108
+ code += "\n";
109
+ code +=
110
+ 'NSString *credentials = [NSString stringWithFormat:@"%@:%@", ' +
111
+ repr(user) +
112
+ ", " +
113
+ repr(password) +
114
+ "];\n";
115
+ code +=
116
+ "NSData *credentialsData = [credentials dataUsingEncoding:NSUTF8StringEncoding];\n";
117
+ code +=
118
+ "NSString *base64Credentials = [credentialsData base64EncodedStringWithOptions:0];\n";
119
+ }
120
+
121
+ if (request.headers.length || request.urls[0].auth) {
122
+ const headerLines = [];
123
+ for (const [key, value] of request.headers) {
124
+ if (value === null) {
125
+ continue;
126
+ }
127
+ if (
128
+ key.isString() &&
129
+ reservedHeaders.includes(key.toLowerCase().toString())
130
+ ) {
131
+ warnings.push([
132
+ "reserved-header",
133
+ key.toString() + " is a reserved header",
134
+ ]);
135
+ }
136
+ headerLines.push(" " + repr(key) + ": " + repr(value));
137
+ }
138
+ if (request.urls[0].auth) {
139
+ warnings.push(["reserved-header", "Authorization is a reserved header"]);
140
+ headerLines.push(
141
+ ' @"Authorization": [NSString stringWithFormat:@"Basic %@", base64Credentials]',
142
+ );
143
+ }
144
+ if (headerLines.length) {
145
+ code += "NSDictionary *headers = @{\n";
146
+ code += headerLines.join(",\n") + "\n";
147
+ code += "};\n";
148
+ code += "\n";
149
+ }
150
+ }
151
+
152
+ let hasData = false;
153
+ let hasDataStream = false;
154
+ if (request.urls[0].uploadFile) {
155
+ code +=
156
+ "InputStream *dataStream = [InputStream fileAtPath:" +
157
+ // TODO: might need processing
158
+ repr(request.urls[0].uploadFile) +
159
+ "];";
160
+ hasDataStream = true;
161
+ } else if (request.multipartUploads) {
162
+ // TODO
163
+ } else if (request.dataArray && request.dataArray.length >= 1) {
164
+ if (
165
+ request.dataArray.length === 1 &&
166
+ !(request.dataArray[0] instanceof Word) &&
167
+ !request.dataArray[0].name
168
+ ) {
169
+ // TODO: urlencode if necessary
170
+ code +=
171
+ "InputStream *dataStream = [InputStream fileAtPath:" +
172
+ repr(request.dataArray[0].filename) +
173
+ "];";
174
+ hasDataStream = true;
175
+ } else {
176
+ const parts = [];
177
+ if (
178
+ request.dataArray.length === 1 &&
179
+ request.dataArray[0] instanceof Word
180
+ ) {
181
+ const entries = request.dataArray[0].split("&");
182
+ for (const [i, entry] of entries.entries()) {
183
+ const newEntry = i === 0 ? entry : entry.prepend("&");
184
+ parts.push(repr(newEntry));
185
+ }
186
+ } else {
187
+ // TODO: this can be better
188
+ const entries: DataParam[] = [];
189
+ for (const d of request.dataArray) {
190
+ if (d instanceof Word) {
191
+ entries.push(d);
192
+ } else {
193
+ if (d.name) {
194
+ const name = d.name.append("=");
195
+ const lastEntry = entries[entries.length - 1];
196
+ if (entries.length && lastEntry instanceof Word) {
197
+ entries[entries.length - 1] = mergeWords(lastEntry, name);
198
+ } else {
199
+ entries.push(name);
200
+ }
201
+ }
202
+ entries.push(d);
203
+ }
204
+ }
205
+ for (const entry of entries) {
206
+ if (entry instanceof Word) {
207
+ parts.push(repr(entry));
208
+ } else {
209
+ // TODO: handle file type
210
+ parts.push(
211
+ "[NSString stringWithContentsOfFile:" +
212
+ repr(entry.filename) +
213
+ " encoding:NSUTF8StringEncoding error:nil];",
214
+ );
215
+ }
216
+ }
217
+ }
218
+
219
+ const [firstPart, ...restParts] = parts;
220
+ code +=
221
+ "NSMutableData *data = [[NSMutableData alloc] initWithData:[" +
222
+ firstPart +
223
+ " dataUsingEncoding:NSUTF8StringEncoding]];\n";
224
+ for (const part of restParts) {
225
+ code +=
226
+ "[data appendData:[" +
227
+ part +
228
+ " dataUsingEncoding:NSUTF8StringEncoding]];\n";
229
+ }
230
+ code += "\n";
231
+ hasData = true;
232
+ }
233
+ }
234
+ if (
235
+ request.timeout &&
236
+ !eq(request.timeout, "60") &&
237
+ !eq(request.timeout, "60.0")
238
+ ) {
239
+ code +=
240
+ "NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url\n";
241
+ code +=
242
+ " cachePolicy:NSURLRequestUseProtocolCachePolicy\n";
243
+ code +=
244
+ " timeoutInterval:" +
245
+ // TODO: verify/escape or parse
246
+ request.timeout.toString() +
247
+ "];\n";
248
+ } else {
249
+ code +=
250
+ "NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];\n";
251
+ }
252
+
253
+ if (!eq(request.urls[0].method, "GET")) {
254
+ code += "[request setHTTPMethod:" + repr(request.urls[0].method) + "];\n";
255
+ }
256
+ if (request.headers.length || request.urls[0].auth) {
257
+ code += "[request setAllHTTPHeaderFields:headers];\n";
258
+ }
259
+ if (hasData) {
260
+ code += "[request setHTTPBody:data];\n";
261
+ } else if (hasDataStream) {
262
+ // TODO: does this work?
263
+ code += "[request setHTTPBodyStream:dataStream];\n";
264
+ }
265
+
266
+ code += "\n";
267
+ // TODO: TLSMinimumSupportedProtocolVersion
268
+ code +=
269
+ "NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];\n";
270
+ code +=
271
+ "NSURLSession *session = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];\n";
272
+ code +=
273
+ "NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {\n";
274
+ code += " if (error) {\n";
275
+ code += ' NSLog(@"%@", error);\n';
276
+ code += " } else {\n";
277
+ code +=
278
+ " NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;\n";
279
+ code += ' NSLog(@"%@", httpResponse);\n';
280
+ code += " }\n";
281
+ code += "}];\n";
282
+ code += "[dataTask resume];\n";
283
+
284
+ return code;
285
+ }
286
+
287
+ export function toObjectiveCWarn(
288
+ curlCommand: string | string[],
289
+ warnings: Warnings = [],
290
+ ): [string, Warnings] {
291
+ const requests = parse(curlCommand, supportedArgs, warnings);
292
+ const code = _toObjectiveC(requests, warnings);
293
+ return [code, warnings];
294
+ }
295
+ export function toObjectiveC(curlCommand: string | string[]): string {
296
+ return toObjectiveCWarn(curlCommand)[0];
297
+ }