'use strict'; var url = require('url'); var qs = require('qs'); var stringifyObject9 = require('stringify-object'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var stringifyObject9__default = /*#__PURE__*/_interopDefault(stringifyObject9); // src/index.ts // src/helpers/headers.ts var getHeaderName = (headers, name) => Object.keys(headers).find((header) => header.toLowerCase() === name.toLowerCase()); var getHeader = (headers, name) => { const headerName = getHeaderName(headers, name); if (!headerName) { return void 0; } return headers[headerName]; }; var hasHeader = (headers, name) => Boolean(getHeaderName(headers, name)); var isMimeTypeJSON = (mimeType) => ["application/json", "application/x-json", "text/json", "text/x-json", "+json"].some( (type) => mimeType.indexOf(type) > -1 ); // src/helpers/reducer.ts var reducer = (accumulator, pair) => { const currentValue = accumulator[pair.name]; if (currentValue === void 0) { accumulator[pair.name] = pair.value; return accumulator; } if (Array.isArray(currentValue)) { currentValue.push(pair.value); return accumulator; } accumulator[pair.name] = [currentValue, pair.value]; return accumulator; }; // src/helpers/code-builder.ts var DEFAULT_INDENTATION_CHARACTER = ""; var DEFAULT_LINE_JOIN = "\n"; var CodeBuilder = class { /** * Helper object to format and aggragate lines of code. * Lines are aggregated in a `code` array, and need to be joined to obtain a proper code snippet. */ constructor({ indent, join } = {}) { this.postProcessors = []; this.code = []; this.indentationCharacter = DEFAULT_INDENTATION_CHARACTER; this.lineJoin = DEFAULT_LINE_JOIN; /** * Add given indentation level to given line of code */ this.indentLine = (line, indentationLevel = 0) => { const indent = this.indentationCharacter.repeat(indentationLevel); return `${indent}${line}`; }; /** * Add the line at the beginning of the current lines */ this.unshift = (line, indentationLevel) => { const newLine = this.indentLine(line, indentationLevel); this.code.unshift(newLine); }; /** * Add the line at the end of the current lines */ this.push = (line, indentationLevel) => { const newLine = this.indentLine(line, indentationLevel); this.code.push(newLine); }; /** * Add an empty line at the end of current lines */ this.blank = () => { this.code.push(""); }; /** * Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added */ this.join = () => { const unreplacedCode = this.code.join(this.lineJoin); const replacedOutput = this.postProcessors.reduce((accumulator, replacer) => replacer(accumulator), unreplacedCode); return replacedOutput; }; /** * Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step. * To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on. */ this.addPostProcessor = (postProcessor) => { this.postProcessors = [...this.postProcessors, postProcessor]; }; this.indentationCharacter = indent || DEFAULT_INDENTATION_CHARACTER; this.lineJoin = join ?? DEFAULT_LINE_JOIN; } }; // src/helpers/escape.ts function escapeString(rawValue, options = {}) { const { delimiter = '"', escapeChar = "\\", escapeNewlines = true } = options; const stringValue = rawValue.toString(); return [...stringValue].map((c2) => { if (c2 === "\b") { return `${escapeChar}b`; } else if (c2 === " ") { return `${escapeChar}t`; } else if (c2 === "\n") { if (escapeNewlines) { return `${escapeChar}n`; } return c2; } else if (c2 === "\f") { return `${escapeChar}f`; } else if (c2 === "\r") { if (escapeNewlines) { return `${escapeChar}r`; } return c2; } else if (c2 === escapeChar) { return escapeChar + escapeChar; } else if (c2 === delimiter) { return escapeChar + delimiter; } else if (c2 < " " || c2 > "~") { return JSON.stringify(c2).slice(1, -1); } return c2; }).join(""); } var escapeForSingleQuotes = (value) => escapeString(value, { delimiter: "'" }); var escapeForDoubleQuotes = (value) => escapeString(value, { delimiter: '"' }); // src/targets/c/libcurl/client.ts var libcurl = { info: { key: "libcurl", title: "Libcurl", link: "http://curl.haxx.se/libcurl", description: "Simple REST and HTTP API Client for C", extname: ".c" }, convert: ({ method, fullUrl, headersObj, allHeaders, postData }) => { const { push, blank, join } = new CodeBuilder(); push("CURL *hnd = curl_easy_init();"); blank(); push(`curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "${method.toUpperCase()}");`); push("curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);"); push(`curl_easy_setopt(hnd, CURLOPT_URL, "${fullUrl}");`); const headers = Object.keys(headersObj); if (headers.length) { blank(); push("struct curl_slist *headers = NULL;"); headers.forEach((header) => { push(`headers = curl_slist_append(headers, "${header}: ${escapeForDoubleQuotes(headersObj[header])}");`); }); push("curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);"); } if (allHeaders.cookie) { blank(); push(`curl_easy_setopt(hnd, CURLOPT_COOKIE, "${allHeaders.cookie}");`); } if (postData.text) { blank(); push(`curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, ${JSON.stringify(postData.text)});`); } blank(); push("CURLcode ret = curl_easy_perform(hnd);"); return join(); } }; // src/targets/c/target.ts var c = { info: { key: "c", title: "C", default: "libcurl", cli: "c" }, clientsById: { libcurl } }; // src/targets/clojure/clj_http/client.ts var Keyword = class { constructor(name) { this.name = ""; this.toString = () => `:${this.name}`; this.name = name; } }; var File = class { constructor(path) { this.path = ""; this.toString = () => `(clojure.java.io/file "${this.path}")`; this.path = path; } }; var jsType = (input) => { if (input === void 0) { return null; } if (input === null) { return "null"; } return input.constructor.name.toLowerCase(); }; var objEmpty = (input) => { if (input === void 0) { return true; } else if (jsType(input) === "object") { return Object.keys(input).length === 0; } return false; }; var filterEmpty = (input) => { Object.keys(input).filter((x) => objEmpty(input[x])).forEach((x) => { delete input[x]; }); return input; }; var padBlock = (padSize, input) => { const padding = " ".repeat(padSize); return input.replace(/\n/g, ` ${padding}`); }; var jsToEdn = (js) => { switch (jsType(js)) { case "string": return `"${js.replace(/"/g, '\\"')}"`; case "file": return js.toString(); case "keyword": return js.toString(); case "null": return "nil"; case "regexp": return `#"${js.source}"`; case "object": { const obj = Object.keys(js).reduce((accumulator, key) => { const val = padBlock(key.length + 2, jsToEdn(js[key])); return `${accumulator}:${key} ${val} `; }, "").trim(); return `{${padBlock(1, obj)}}`; } case "array": { const arr = js.reduce((accumulator, value) => `${accumulator} ${jsToEdn(value)}`, "").trim(); return `[${padBlock(1, arr)}]`; } default: return js.toString(); } }; var clj_http = { info: { key: "clj_http", title: "clj-http", link: "https://github.com/dakrone/clj-http", description: "An idiomatic clojure http client wrapping the apache client.", extname: ".clj" }, convert: ({ queryObj, method, postData, url, allHeaders }, options) => { const { push, join } = new CodeBuilder({ indent: options?.indent }); const methods = ["get", "post", "put", "delete", "patch", "head", "options"]; method = method.toLowerCase(); if (!methods.includes(method)) { push("Method not supported"); return join(); } const params2 = { headers: allHeaders, "query-params": queryObj }; switch (postData.mimeType) { case "application/json": { params2["content-type"] = new Keyword("json"); params2["form-params"] = postData.jsonObj; const header = getHeaderName(params2.headers, "content-type"); if (header) { delete params2.headers[header]; } } break; case "application/x-www-form-urlencoded": { params2["form-params"] = postData.paramsObj; const header = getHeaderName(params2.headers, "content-type"); if (header) { delete params2.headers[header]; } } break; case "text/plain": { params2.body = postData.text; const header = getHeaderName(params2.headers, "content-type"); if (header) { delete params2.headers[header]; } } break; case "multipart/form-data": { if (postData.params) { params2.multipart = postData.params.map((param) => { if (param.fileName && !param.value) { return { name: param.name, content: new File(param.fileName) }; } return { name: param.name, content: param.value }; }); const header = getHeaderName(params2.headers, "content-type"); if (header) { delete params2.headers[header]; } } break; } } switch (getHeader(params2.headers, "accept")) { case "application/json": { params2.accept = new Keyword("json"); const header = getHeaderName(params2.headers, "accept"); if (header) { delete params2.headers[header]; } } break; } push("(require '[clj-http.client :as client])\n"); if (objEmpty(filterEmpty(params2))) { push(`(client/${method} "${url}")`); } else { const padding = 11 + method.length + url.length; const formattedParams = padBlock(padding, jsToEdn(filterEmpty(params2))); push(`(client/${method} "${url}" ${formattedParams})`); } return join(); } }; // src/targets/clojure/target.ts var clojure = { info: { key: "clojure", title: "Clojure", default: "clj_http" }, clientsById: { clj_http } }; // src/targets/csharp/httpclient/client.ts var getDecompressionMethods = (allHeaders) => { let acceptEncodings = getHeader(allHeaders, "accept-encoding"); if (!acceptEncodings) { return []; } const supportedMethods2 = { gzip: "DecompressionMethods.GZip", deflate: "DecompressionMethods.Deflate" }; const methods = []; if (typeof acceptEncodings === "string") { acceptEncodings = [acceptEncodings]; } acceptEncodings.forEach((acceptEncoding) => { acceptEncoding.split(",").forEach((encoding) => { const match = /\s*([^;\s]+)/.exec(encoding); if (match) { const method = supportedMethods2[match[1]]; if (method) { methods.push(method); } } }); }); return methods; }; var httpclient = { info: { key: "httpclient", title: "HttpClient", link: "https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient", description: ".NET Standard HTTP Client", extname: ".cs" }, convert: ({ allHeaders, postData, method, fullUrl }, options) => { const opts = { indent: " ", ...options }; const { push, join } = new CodeBuilder({ indent: opts.indent }); push("using System.Net.Http.Headers;"); let clienthandler = ""; const cookies = Boolean(allHeaders.cookie); const decompressionMethods = getDecompressionMethods(allHeaders); if (cookies || decompressionMethods.length) { clienthandler = "clientHandler"; push("var clientHandler = new HttpClientHandler"); push("{"); if (cookies) { push("UseCookies = false,", 1); } if (decompressionMethods.length) { push(`AutomaticDecompression = ${decompressionMethods.join(" | ")},`, 1); } push("};"); } push(`var client = new HttpClient(${clienthandler});`); push("var request = new HttpRequestMessage"); push("{"); const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"]; method = method.toUpperCase(); if (method && methods.includes(method)) { method = `HttpMethod.${method[0]}${method.substring(1).toLowerCase()}`; } else { method = `new HttpMethod("${method}")`; } push(`Method = ${method},`, 1); push(`RequestUri = new Uri("${fullUrl}"),`, 1); const headers = Object.keys(allHeaders).filter((header) => { switch (header.toLowerCase()) { case "content-type": case "content-length": case "accept-encoding": return false; default: return true; } }); if (headers.length) { push("Headers =", 1); push("{", 1); headers.forEach((key) => { push(`{ "${key}", "${escapeForDoubleQuotes(allHeaders[key])}" },`, 2); }); push("},", 1); } if (postData.text) { const contentType = postData.mimeType; switch (contentType) { case "application/x-www-form-urlencoded": push("Content = new FormUrlEncodedContent(new Dictionary", 1); push("{", 1); postData.params?.forEach((param) => { push(`{ "${param.name}", "${param.value}" },`, 2); }); push("}),", 1); break; case "multipart/form-data": push("Content = new MultipartFormDataContent", 1); push("{", 1); postData.params?.forEach((param) => { push(`new StringContent(${JSON.stringify(param.value || "")})`, 2); push("{", 2); push("Headers =", 3); push("{", 3); if (param.contentType) { push(`ContentType = new MediaTypeHeaderValue("${param.contentType}"),`, 4); } push('ContentDisposition = new ContentDispositionHeaderValue("form-data")', 4); push("{", 4); push(`Name = "${param.name}",`, 5); if (param.fileName) { push(`FileName = "${param.fileName}",`, 5); } push("}", 4); push("}", 3); push("},", 2); }); push("},", 1); break; default: push(`Content = new StringContent(${JSON.stringify(postData.text || "")})`, 1); push("{", 1); push("Headers =", 2); push("{", 2); push(`ContentType = new MediaTypeHeaderValue("${contentType}")`, 3); push("}", 2); push("}", 1); break; } } push("};"); push("using (var response = await client.SendAsync(request))"); push("{"); push("response.EnsureSuccessStatusCode();", 1); push("var body = await response.Content.ReadAsStringAsync();", 1); push("Console.WriteLine(body);", 1); push("}"); return join(); } }; // src/targets/csharp/restsharp/client.ts function title(s) { return s[0].toUpperCase() + s.slice(1).toLowerCase(); } var restsharp = { info: { key: "restsharp", title: "RestSharp", link: "http://restsharp.org/", description: "Simple REST and HTTP API Client for .NET", extname: ".cs", installation: "dotnet add package RestSharp" }, convert: ({ method, fullUrl, headersObj, cookies, postData, uriObj }) => { const { push, join } = new CodeBuilder(); const isSupportedMethod = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"].includes( method.toUpperCase() ); if (!isSupportedMethod) { return "Method not supported"; } push("using RestSharp;\n\n"); push(`var options = new RestClientOptions("${fullUrl}");`); push("var client = new RestClient(options);"); push('var request = new RestRequest("");'); const isMultipart = postData.mimeType && postData.mimeType === "multipart/form-data"; if (isMultipart) { push("request.AlwaysMultipartFormData = true;"); } Object.keys(headersObj).forEach((key) => { if (postData.mimeType && key.toLowerCase() === "content-type" && postData.text) { if (isMultipart && postData.boundary) { push(`request.FormBoundary = "${postData.boundary}";`); } return; } push(`request.AddHeader("${key}", "${escapeForDoubleQuotes(headersObj[key])}");`); }); cookies.forEach(({ name, value }) => { push(`request.AddCookie("${name}", "${escapeForDoubleQuotes(value)}", "${uriObj.pathname}", "${uriObj.host}");`); }); switch (postData.mimeType) { case "multipart/form-data": if (!postData.params) break; postData.params.forEach((param) => { if (param.fileName) { push(`request.AddFile("${param.name}", "${param.fileName}");`); } else { push(`request.AddParameter("${param.name}", "${param.value}");`); } }); break; case "application/x-www-form-urlencoded": if (!postData.params) break; postData.params.forEach((param) => { push(`request.AddParameter("${param.name}", "${param.value}");`); }); break; case "application/json": { if (!postData.text) break; const text = JSON.stringify(postData.text); push(`request.AddJsonBody(${text}, false);`); break; } default: if (!postData.text) break; push(`request.AddStringBody("${postData.text}", "${postData.mimeType}");`); } push(`var response = await client.${title(method)}Async(request); `); push('Console.WriteLine("{0}", response.Content);\n'); return join(); } }; // src/targets/csharp/target.ts var csharp = { info: { key: "csharp", title: "C#", default: "restsharp", cli: "dotnet" }, clientsById: { httpclient, restsharp } }; // src/targets/go/native/client.ts var native = { info: { key: "native", title: "NewRequest", link: "http://golang.org/pkg/net/http/#NewRequest", description: "Golang HTTP client request", extname: ".go" }, convert: ({ postData, method, allHeaders, fullUrl }, options = {}) => { const { blank, push, join } = new CodeBuilder({ indent: " " }); const { showBoilerplate = true, checkErrors = false, printBody = true, timeout = -1 } = options; const errorPlaceholder = checkErrors ? "err" : "_"; const indent = showBoilerplate ? 1 : 0; const errorCheck = () => { if (checkErrors) { push("if err != nil {", indent); push("panic(err)", indent + 1); push("}", indent); } }; if (showBoilerplate) { push("package main"); blank(); push("import ("); push('"fmt"', indent); if (timeout > 0) { push('"time"', indent); } if (postData.text) { push('"strings"', indent); } push('"net/http"', indent); if (printBody) { push('"io"', indent); } push(")"); blank(); push("func main() {"); blank(); } const hasTimeout = timeout > 0; const hasClient = hasTimeout; const client = hasClient ? "client" : "http.DefaultClient"; if (hasClient) { push("client := http.Client{", indent); if (hasTimeout) { push(`Timeout: time.Duration(${timeout} * time.Second),`, indent + 1); } push("}", indent); blank(); } push(`url := "${fullUrl}"`, indent); blank(); if (postData.text) { push(`payload := strings.NewReader(${JSON.stringify(postData.text)})`, indent); blank(); push(`req, ${errorPlaceholder} := http.NewRequest("${method}", url, payload)`, indent); blank(); } else { push(`req, ${errorPlaceholder} := http.NewRequest("${method}", url, nil)`, indent); blank(); } errorCheck(); if (Object.keys(allHeaders).length) { Object.keys(allHeaders).forEach((key) => { push(`req.Header.Add("${key}", "${escapeForDoubleQuotes(allHeaders[key])}")`, indent); }); blank(); } push(`res, ${errorPlaceholder} := ${client}.Do(req)`, indent); errorCheck(); if (printBody) { blank(); push("defer res.Body.Close()", indent); push(`body, ${errorPlaceholder} := io.ReadAll(res.Body)`, indent); errorCheck(); } blank(); if (printBody) { push("fmt.Println(string(body))", indent); } if (showBoilerplate) { blank(); push("}"); } return join(); } }; // src/targets/go/target.ts var go = { info: { key: "go", title: "Go", default: "native", cli: "go" }, clientsById: { native } }; // src/targets/http/http1.1/client.ts var CRLF = "\r\n"; var http11 = { info: { key: "http1.1", title: "HTTP/1.1", link: "https://tools.ietf.org/html/rfc7230", description: "HTTP/1.1 request string in accordance with RFC 7230", extname: null }, convert: ({ method, fullUrl, uriObj, httpVersion, allHeaders, postData }, options) => { const opts = { absoluteURI: false, autoContentLength: true, autoHost: true, ...options }; const { blank, push, join } = new CodeBuilder({ indent: "", join: CRLF }); const requestUrl = opts.absoluteURI ? fullUrl : uriObj.path; push(`${method} ${requestUrl} ${httpVersion}`); const headerKeys = Object.keys(allHeaders); headerKeys.forEach((key) => { const keyCapitalized = key.toLowerCase().replace(/(^|-)(\w)/g, (input) => input.toUpperCase()); push(`${keyCapitalized}: ${allHeaders[key]}`); }); if (opts.autoHost && !headerKeys.includes("host")) { push(`Host: ${uriObj.host}`); } if (opts.autoContentLength && postData.text && !headerKeys.includes("content-length")) { const encoder = new TextEncoder(); const length = encoder.encode(postData.text).length.toString(); push(`Content-Length: ${length}`); } blank(); const headerSection = join(); const messageBody = postData.text || ""; return `${headerSection}${CRLF}${messageBody}`; } }; // src/targets/http/target.ts var http = { info: { key: "http", title: "HTTP", default: "http1.1" }, clientsById: { "http1.1": http11 } }; // src/targets/java/asynchttp/client.ts var asynchttp = { info: { key: "asynchttp", title: "AsyncHttp", link: "https://github.com/AsyncHttpClient/async-http-client", description: "Asynchronous Http and WebSocket Client library for Java", extname: ".java" }, convert: ({ method, allHeaders, postData, fullUrl }, options) => { const opts = { indent: " ", ...options }; const { blank, push, join } = new CodeBuilder({ indent: opts.indent }); push("AsyncHttpClient client = new DefaultAsyncHttpClient();"); push(`client.prepare("${method.toUpperCase()}", "${fullUrl}")`); Object.keys(allHeaders).forEach((key) => { push(`.setHeader("${key}", "${escapeForDoubleQuotes(allHeaders[key])}")`, 1); }); if (postData.text) { push(`.setBody(${JSON.stringify(postData.text)})`, 1); } push(".execute()", 1); push(".toCompletableFuture()", 1); push(".thenAccept(System.out::println)", 1); push(".join();", 1); blank(); push("client.close();"); return join(); } }; // src/targets/java/nethttp/client.ts var nethttp = { info: { key: "nethttp", title: "java.net.http", link: "https://openjdk.java.net/groups/net/httpclient/intro.html", description: "Java Standardized HTTP Client API", extname: ".java" }, convert: ({ allHeaders, fullUrl, method, postData }, options) => { const opts = { indent: " ", ...options }; const { push, join } = new CodeBuilder({ indent: opts.indent }); push("HttpRequest request = HttpRequest.newBuilder()"); push(`.uri(URI.create("${fullUrl}"))`, 2); Object.keys(allHeaders).forEach((key) => { push(`.header("${key}", "${escapeForDoubleQuotes(allHeaders[key])}")`, 2); }); if (postData.text) { push( `.method("${method.toUpperCase()}", HttpRequest.BodyPublishers.ofString(${JSON.stringify(postData.text)}))`, 2 ); } else { push(`.method("${method.toUpperCase()}", HttpRequest.BodyPublishers.noBody())`, 2); } push(".build();", 2); push( "HttpResponse response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());" ); push("System.out.println(response.body());"); return join(); } }; // src/targets/java/okhttp/client.ts var okhttp = { info: { key: "okhttp", title: "OkHttp", link: "http://square.github.io/okhttp/", description: "An HTTP Request Client Library", extname: ".java" }, convert: ({ postData, method, fullUrl, allHeaders }, options) => { const opts = { indent: " ", ...options }; const { push, blank, join } = new CodeBuilder({ indent: opts.indent }); const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD"]; const methodsWithBody = ["POST", "PUT", "DELETE", "PATCH"]; push("OkHttpClient client = new OkHttpClient();"); blank(); if (postData.text) { if (postData.boundary) { push(`MediaType mediaType = MediaType.parse("${postData.mimeType}; boundary=${postData.boundary}");`); } else { push(`MediaType mediaType = MediaType.parse("${postData.mimeType}");`); } push(`RequestBody body = RequestBody.create(mediaType, ${JSON.stringify(postData.text)});`); } push("Request request = new Request.Builder()"); push(`.url("${fullUrl}")`, 1); if (!methods.includes(method.toUpperCase())) { if (postData.text) { push(`.method("${method.toUpperCase()}", body)`, 1); } else { push(`.method("${method.toUpperCase()}", null)`, 1); } } else if (methodsWithBody.includes(method.toUpperCase())) { if (postData.text) { push(`.${method.toLowerCase()}(body)`, 1); } else { push(`.${method.toLowerCase()}(null)`, 1); } } else { push(`.${method.toLowerCase()}()`, 1); } Object.keys(allHeaders).forEach((key) => { push(`.addHeader("${key}", "${escapeForDoubleQuotes(allHeaders[key])}")`, 1); }); push(".build();", 1); blank(); push("Response response = client.newCall(request).execute();"); return join(); } }; // src/targets/java/unirest/client.ts var unirest = { info: { key: "unirest", title: "Unirest", link: "http://unirest.io/java.html", description: "Lightweight HTTP Request Client Library", extname: ".java" }, convert: ({ method, allHeaders, postData, fullUrl }, options) => { const opts = { indent: " ", ...options }; const { join, push } = new CodeBuilder({ indent: opts.indent }); const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; if (!methods.includes(method.toUpperCase())) { push(`HttpResponse response = Unirest.customMethod("${method.toUpperCase()}","${fullUrl}")`); } else { push(`HttpResponse response = Unirest.${method.toLowerCase()}("${fullUrl}")`); } Object.keys(allHeaders).forEach((key) => { push(`.header("${key}", "${escapeForDoubleQuotes(allHeaders[key])}")`, 1); }); if (postData.text) { push(`.body(${JSON.stringify(postData.text)})`, 1); } push(".asString();", 1); return join(); } }; // src/targets/java/target.ts var java = { info: { key: "java", title: "Java", default: "unirest" }, clientsById: { asynchttp, nethttp, okhttp, unirest } }; var axios = { info: { key: "axios", title: "Axios", link: "https://github.com/axios/axios", description: "Promise based HTTP client for the browser and node.js", extname: ".js", installation: "npm install axios --save" }, convert: ({ allHeaders, method, url, queryObj, postData }, options) => { const opts = { indent: " ", ...options }; const { blank, push, join, addPostProcessor } = new CodeBuilder({ indent: opts.indent }); push("import axios from 'axios';"); blank(); const requestOptions = { method, url }; if (Object.keys(queryObj).length) { requestOptions.params = queryObj; } if (Object.keys(allHeaders).length) { requestOptions.headers = allHeaders; } switch (postData.mimeType) { case "application/x-www-form-urlencoded": if (postData.params) { push("const encodedParams = new URLSearchParams();"); postData.params.forEach((param) => { push(`encodedParams.set('${param.name}', '${param.value}');`); }); blank(); requestOptions.data = "encodedParams,"; addPostProcessor((code) => code.replace(/'encodedParams,'/, "encodedParams,")); } break; case "application/json": if (postData.jsonObj) { requestOptions.data = postData.jsonObj; } break; case "multipart/form-data": if (!postData.params) { break; } push("const form = new FormData();"); postData.params.forEach((param) => { push(`form.append('${param.name}', '${param.value || param.fileName || ""}');`); }); blank(); requestOptions.data = "[form]"; break; default: if (postData.text) { requestOptions.data = postData.text; } } const optionString = stringifyObject9__default.default(requestOptions, { indent: " ", inlineCharacterLimit: 80 }).replace('"[form]"', "form"); push(`const options = ${optionString};`); blank(); push("axios"); push(".request(options)", 1); push(".then(function (response) {", 1); push("console.log(response.data);", 2); push("})", 1); push(".catch(function (error) {", 1); push("console.error(error);", 2); push("});", 1); return join(); } }; var fetch = { info: { key: "fetch", title: "fetch", link: "https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch", description: "Perform asynchronous HTTP requests with the Fetch API", extname: ".js" }, convert: ({ method, allHeaders, postData, fullUrl }, inputOpts) => { const opts = { indent: " ", credentials: null, ...inputOpts }; const { blank, join, push } = new CodeBuilder({ indent: opts.indent }); const options = { method }; if (Object.keys(allHeaders).length) { options.headers = allHeaders; } if (opts.credentials !== null) { options.credentials = opts.credentials; } switch (postData.mimeType) { case "application/x-www-form-urlencoded": options.body = postData.paramsObj ? postData.paramsObj : postData.text; break; case "application/json": if (postData.jsonObj) { options.body = postData.jsonObj; } break; case "multipart/form-data": if (!postData.params) { break; } const contentTypeHeader = getHeaderName(allHeaders, "content-type"); if (contentTypeHeader) { delete allHeaders[contentTypeHeader]; } push("const form = new FormData();"); postData.params.forEach((param) => { push(`form.append('${param.name}', '${param.value || param.fileName || ""}');`); }); blank(); break; default: if (postData.text) { options.body = postData.text; } } if (options.headers && !Object.keys(options.headers).length) { delete options.headers; } push( `const options = ${stringifyObject9__default.default(options, { indent: opts.indent, inlineCharacterLimit: 80, // The Fetch API body only accepts string parameters, but stringified JSON can be difficult // to read, so we keep the object as a literal and use this transform function to wrap the // literal in a `JSON.stringify` call. transform: (object, property, originalResult) => { if (property === "body") { if (postData.mimeType === "application/x-www-form-urlencoded") { return `new URLSearchParams(${originalResult})`; } else if (postData.mimeType === "application/json") { return `JSON.stringify(${originalResult})`; } } return originalResult; } })};` ); blank(); if (postData.params && postData.mimeType === "multipart/form-data") { push("options.body = form;"); blank(); } push(`fetch('${fullUrl}', options)`); push(".then(response => response.json())", 1); push(".then(response => console.log(response))", 1); push(".catch(err => console.error(err));", 1); return join(); } }; var jquery = { info: { key: "jquery", title: "jQuery", link: "http://api.jquery.com/jquery.ajax/", description: "Perform an asynchronous HTTP (Ajax) requests with jQuery", extname: ".js" }, convert: ({ fullUrl, method, allHeaders, postData }, options) => { const opts = { indent: " ", ...options }; const { blank, push, join } = new CodeBuilder({ indent: opts.indent }); const settings = { async: true, crossDomain: true, url: fullUrl, method, headers: allHeaders }; switch (postData.mimeType) { case "application/x-www-form-urlencoded": settings.data = postData.paramsObj ? postData.paramsObj : postData.text; break; case "application/json": settings.processData = false; settings.data = postData.text; break; case "multipart/form-data": if (!postData.params) { break; } push("const form = new FormData();"); postData.params.forEach((param) => { push(`form.append('${param.name}', '${param.value || param.fileName || ""}');`); }); settings.processData = false; settings.contentType = false; settings.mimeType = "multipart/form-data"; settings.data = "[form]"; if (hasHeader(allHeaders, "content-type")) { if (getHeader(allHeaders, "content-type")?.includes("boundary")) { const headerName = getHeaderName(allHeaders, "content-type"); if (headerName) { delete settings.headers[headerName]; } } } blank(); break; default: if (postData.text) { settings.data = postData.text; } } const stringifiedSettings = stringifyObject9__default.default(settings, { indent: opts.indent }).replace("'[form]'", "form"); push(`const settings = ${stringifiedSettings};`); blank(); push("$.ajax(settings).done(function (response) {"); push("console.log(response);", 1); push("});"); return join(); } }; var xhr = { info: { key: "xhr", title: "XMLHttpRequest", link: "https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest", description: "W3C Standard API that provides scripted client functionality", extname: ".js" }, convert: ({ postData, allHeaders, method, fullUrl }, options) => { const opts = { indent: " ", cors: true, ...options }; const { blank, push, join } = new CodeBuilder({ indent: opts.indent }); switch (postData.mimeType) { case "application/json": push( `const data = JSON.stringify(${stringifyObject9__default.default(postData.jsonObj, { indent: opts.indent })});` ); blank(); break; case "multipart/form-data": if (!postData.params) { break; } push("const data = new FormData();"); postData.params.forEach((param) => { push(`data.append('${param.name}', '${param.value || param.fileName || ""}');`); }); if (hasHeader(allHeaders, "content-type")) { if (getHeader(allHeaders, "content-type")?.includes("boundary")) { const headerName = getHeaderName(allHeaders, "content-type"); if (headerName) { delete allHeaders[headerName]; } } } blank(); break; default: push(`const data = ${postData.text ? `'${postData.text}'` : "null"};`); blank(); } push("const xhr = new XMLHttpRequest();"); if (opts.cors) { push("xhr.withCredentials = true;"); } blank(); push("xhr.addEventListener('readystatechange', function () {"); push("if (this.readyState === this.DONE) {", 1); push("console.log(this.responseText);", 2); push("}", 1); push("});"); blank(); push(`xhr.open('${method}', '${fullUrl}');`); Object.keys(allHeaders).forEach((key) => { push(`xhr.setRequestHeader('${key}', '${escapeForSingleQuotes(allHeaders[key])}');`); }); blank(); push("xhr.send(data);"); return join(); } }; // src/targets/javascript/target.ts var javascript = { info: { key: "javascript", title: "JavaScript", default: "xhr" }, clientsById: { xhr, axios, fetch, jquery } }; // src/targets/json/native/client.ts var native2 = { info: { key: "native", title: "Native JSON", link: "https://www.json.org/json-en.html", description: "A JSON represetation of any HAR payload.", extname: ".json" }, convert: ({ postData }, inputOpts) => { const opts = { indent: " ", ...inputOpts }; let payload = ""; switch (postData.mimeType) { case "application/x-www-form-urlencoded": payload = postData.paramsObj ? postData.paramsObj : postData.text; break; case "application/json": if (postData.jsonObj) { payload = postData.jsonObj; } break; case "multipart/form-data": if (!postData.params) { break; } const multipartPayload = {}; postData.params.forEach((param) => { multipartPayload[param.name] = param.value; }); payload = multipartPayload; break; default: if (postData.text) { payload = postData.text; } } if (typeof payload === "undefined" || payload === "") { return "No JSON body"; } return JSON.stringify(payload, null, opts.indent); } }; // src/targets/json/target.ts var json = { info: { key: "json", title: "JSON", default: "native" }, clientsById: { native: native2 } }; // src/targets/kotlin/okhttp/client.ts var okhttp2 = { info: { key: "okhttp", title: "OkHttp", link: "http://square.github.io/okhttp/", description: "An HTTP Request Client Library", extname: ".kt" }, convert: ({ postData, fullUrl, method, allHeaders }, options) => { const opts = { indent: " ", ...options }; const { blank, join, push } = new CodeBuilder({ indent: opts.indent }); const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD"]; const methodsWithBody = ["POST", "PUT", "DELETE", "PATCH"]; push("val client = OkHttpClient()"); blank(); if (postData.text) { if (postData.boundary) { push(`val mediaType = MediaType.parse("${postData.mimeType}; boundary=${postData.boundary}")`); } else { push(`val mediaType = MediaType.parse("${postData.mimeType}")`); } push(`val body = RequestBody.create(mediaType, ${JSON.stringify(postData.text)})`); } push("val request = Request.Builder()"); push(`.url("${fullUrl}")`, 1); if (!methods.includes(method.toUpperCase())) { if (postData.text) { push(`.method("${method.toUpperCase()}", body)`, 1); } else { push(`.method("${method.toUpperCase()}", null)`, 1); } } else if (methodsWithBody.includes(method.toUpperCase())) { if (postData.text) { push(`.${method.toLowerCase()}(body)`, 1); } else { push(`.${method.toLowerCase()}(null)`, 1); } } else { push(`.${method.toLowerCase()}()`, 1); } Object.keys(allHeaders).forEach((key) => { push(`.addHeader("${key}", "${escapeForDoubleQuotes(allHeaders[key])}")`, 1); }); push(".build()", 1); blank(); push("val response = client.newCall(request).execute()"); return join(); } }; // src/targets/kotlin/target.ts var kotlin = { info: { key: "kotlin", title: "Kotlin", default: "okhttp" }, clientsById: { okhttp: okhttp2 } }; var axios2 = { info: { key: "axios", title: "Axios", link: "https://github.com/axios/axios", description: "Promise based HTTP client for the browser and node.js", extname: ".cjs", installation: "npm install axios --save" }, convert: ({ method, fullUrl, allHeaders, postData }, options) => { const opts = { indent: " ", ...options }; const { blank, join, push, addPostProcessor } = new CodeBuilder({ indent: opts.indent }); push("const axios = require('axios');"); const reqOpts = { method, url: fullUrl }; if (Object.keys(allHeaders).length) { reqOpts.headers = allHeaders; } switch (postData.mimeType) { case "application/x-www-form-urlencoded": if (postData.params) { push("const { URLSearchParams } = require('url');"); blank(); push("const encodedParams = new URLSearchParams();"); postData.params.forEach((param) => { push(`encodedParams.set('${param.name}', '${param.value}');`); }); blank(); reqOpts.data = "encodedParams,"; addPostProcessor((code) => code.replace(/'encodedParams,'/, "encodedParams,")); } break; case "application/json": blank(); if (postData.jsonObj) { reqOpts.data = postData.jsonObj; } break; default: blank(); if (postData.text) { reqOpts.data = postData.text; } } const stringifiedOptions = stringifyObject9__default.default(reqOpts, { indent: " ", inlineCharacterLimit: 80 }); push(`const options = ${stringifiedOptions};`); blank(); push("axios"); push(".request(options)", 1); push(".then(function (response) {", 1); push("console.log(response.data);", 2); push("})", 1); push(".catch(function (error) {", 1); push("console.error(error);", 2); push("});", 1); return join(); } }; var fetch2 = { info: { key: "fetch", title: "Fetch", link: "https://github.com/bitinn/node-fetch", description: "Simplified HTTP node-fetch client", extname: ".cjs", installation: "npm install node-fetch@2 --save" }, convert: ({ method, fullUrl, postData, headersObj, cookies }, options) => { const opts = { indent: " ", ...options }; let includeFS = false; const { blank, push, join, unshift } = new CodeBuilder({ indent: opts.indent }); push("const fetch = require('node-fetch');"); const url = fullUrl; const reqOpts = { method }; if (Object.keys(headersObj).length) { reqOpts.headers = headersObj; } switch (postData.mimeType) { case "application/x-www-form-urlencoded": unshift("const { URLSearchParams } = require('url');"); push("const encodedParams = new URLSearchParams();"); blank(); postData.params?.forEach((param) => { push(`encodedParams.set('${param.name}', '${param.value}');`); }); reqOpts.body = "encodedParams"; break; case "application/json": if (postData.jsonObj) { reqOpts.body = postData.jsonObj; } break; case "multipart/form-data": if (!postData.params) { break; } const contentTypeHeader = getHeaderName(headersObj, "content-type"); if (contentTypeHeader) { delete headersObj[contentTypeHeader]; } unshift("const FormData = require('form-data');"); push("const formData = new FormData();"); blank(); postData.params.forEach((param) => { if (!param.fileName && !param.fileName && !param.contentType) { push(`formData.append('${param.name}', '${param.value}');`); return; } if (param.fileName) { includeFS = true; push(`formData.append('${param.name}', fs.createReadStream('${param.fileName}'));`); } }); break; default: if (postData.text) { reqOpts.body = postData.text; } } if (cookies.length) { const cookiesString = cookies.map(({ name, value }) => `${encodeURIComponent(name)}=${encodeURIComponent(value)}`).join("; "); if (reqOpts.headers) { reqOpts.headers.cookie = cookiesString; } else { reqOpts.headers = {}; reqOpts.headers.cookie = cookiesString; } } blank(); push(`const url = '${url}';`); if (reqOpts.headers && !Object.keys(reqOpts.headers).length) { delete reqOpts.headers; } const stringifiedOptions = stringifyObject9__default.default(reqOpts, { indent: " ", inlineCharacterLimit: 80, // The Fetch API body only accepts string parameters, but stringified JSON can be difficult to // read, so we keep the object as a literal and use this transform function to wrap the literal // in a `JSON.stringify` call. transform: (object, property, originalResult) => { if (property === "body" && postData.mimeType === "application/json") { return `JSON.stringify(${originalResult})`; } return originalResult; } }); push(`const options = ${stringifiedOptions};`); blank(); if (includeFS) { unshift("const fs = require('fs');"); } if (postData.params && postData.mimeType === "multipart/form-data") { push("options.body = formData;"); blank(); } push("fetch(url, options)"); push(".then(res => res.json())", 1); push(".then(json => console.log(json))", 1); push(".catch(err => console.error('error:' + err));", 1); return join().replace(/'encodedParams'/, "encodedParams").replace(/"fs\.createReadStream\(\\"(.+)\\"\)"/, 'fs.createReadStream("$1")'); } }; var native3 = { info: { key: "native", title: "HTTP", link: "http://nodejs.org/api/http.html#http_http_request_options_callback", description: "Node.js native HTTP interface", extname: ".cjs" }, convert: ({ uriObj, method, allHeaders, postData }, options = {}) => { const { indent = " " } = options; const { blank, join, push, unshift } = new CodeBuilder({ indent }); const reqOpts = { method, hostname: uriObj.hostname, port: uriObj.port, path: uriObj.path, headers: allHeaders }; push(`const http = require('${uriObj.protocol?.replace(":", "")}');`); blank(); push(`const options = ${stringifyObject9__default.default(reqOpts, { indent })};`); blank(); push("const req = http.request(options, function (res) {"); push("const chunks = [];", 1); blank(); push("res.on('data', function (chunk) {", 1); push("chunks.push(chunk);", 2); push("});", 1); blank(); push("res.on('end', function () {", 1); push("const body = Buffer.concat(chunks);", 2); push("console.log(body.toString());", 2); push("});", 1); push("});"); blank(); switch (postData.mimeType) { case "application/x-www-form-urlencoded": if (postData.paramsObj) { unshift("const qs = require('querystring');"); push( `req.write(qs.stringify(${stringifyObject9__default.default(postData.paramsObj, { indent: " ", inlineCharacterLimit: 80 })}));` ); } break; case "application/json": if (postData.jsonObj) { push( `req.write(JSON.stringify(${stringifyObject9__default.default(postData.jsonObj, { indent: " ", inlineCharacterLimit: 80 })}));` ); } break; default: if (postData.text) { push(`req.write(${stringifyObject9__default.default(postData.text, { indent })});`); } } push("req.end();"); return join(); } }; var request = { info: { key: "request", title: "Request", link: "https://github.com/request/request", description: "Simplified HTTP request client", extname: ".cjs", installation: "npm install request --save" }, convert: ({ method, url, fullUrl, postData, headersObj, cookies }, options) => { const opts = { indent: " ", ...options }; let includeFS = false; const { push, blank, join, unshift, addPostProcessor } = new CodeBuilder({ indent: opts.indent }); push("const request = require('request');"); blank(); const reqOpts = { method, url: fullUrl }; if (Object.keys(headersObj).length) { reqOpts.headers = headersObj; } switch (postData.mimeType) { case "application/x-www-form-urlencoded": reqOpts.form = postData.paramsObj; break; case "application/json": if (postData.jsonObj) { reqOpts.body = postData.jsonObj; reqOpts.json = true; } break; case "multipart/form-data": if (!postData.params) { break; } reqOpts.formData = {}; postData.params.forEach((param) => { if (!param.fileName && !param.fileName && !param.contentType) { reqOpts.formData[param.name] = param.value; return; } let attachment = {}; if (param.fileName) { includeFS = true; attachment = { value: `fs.createReadStream(${param.fileName})`, options: { filename: param.fileName, contentType: param.contentType ? param.contentType : null } }; } else if (param.value) { attachment.value = param.value; } reqOpts.formData[param.name] = attachment; }); addPostProcessor((code) => code.replace(/'fs\.createReadStream\((.*)\)'/, "fs.createReadStream('$1')")); break; default: if (postData.text) { reqOpts.body = postData.text; } } if (cookies.length) { reqOpts.jar = "JAR"; push("const jar = request.jar();"); cookies.forEach(({ name, value }) => { push(`jar.setCookie(request.cookie('${encodeURIComponent(name)}=${encodeURIComponent(value)}'), '${url}');`); }); blank(); addPostProcessor((code) => code.replace(/'JAR'/, "jar")); } if (includeFS) { unshift("const fs = require('fs');"); } push(`const options = ${stringifyObject9__default.default(reqOpts, { indent: " ", inlineCharacterLimit: 80 })};`); blank(); push("request(options, function (error, response, body) {"); push("if (error) throw new Error(error);", 1); blank(); push("console.log(body);", 1); push("});"); return join(); } }; var unirest2 = { info: { key: "unirest", title: "Unirest", link: "http://unirest.io/nodejs.html", description: "Lightweight HTTP Request Client Library", extname: ".cjs" }, convert: ({ method, url, cookies, queryObj, postData, headersObj }, options) => { const opts = { indent: " ", ...options }; let includeFS = false; const { addPostProcessor, blank, join, push, unshift } = new CodeBuilder({ indent: opts.indent }); push("const unirest = require('unirest');"); blank(); push(`const req = unirest('${method}', '${url}');`); blank(); if (cookies.length) { push("const CookieJar = unirest.jar();"); cookies.forEach((cookie) => { push(`CookieJar.add('${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}', '${url}');`); }); push("req.jar(CookieJar);"); blank(); } if (Object.keys(queryObj).length) { push(`req.query(${stringifyObject9__default.default(queryObj, { indent: opts.indent })});`); blank(); } if (Object.keys(headersObj).length) { push(`req.headers(${stringifyObject9__default.default(headersObj, { indent: opts.indent })});`); blank(); } switch (postData.mimeType) { case "application/x-www-form-urlencoded": if (postData.paramsObj) { push(`req.form(${stringifyObject9__default.default(postData.paramsObj, { indent: opts.indent })});`); blank(); } break; case "application/json": if (postData.jsonObj) { push("req.type('json');"); push(`req.send(${stringifyObject9__default.default(postData.jsonObj, { indent: opts.indent })});`); blank(); } break; case "multipart/form-data": { if (!postData.params) { break; } const multipart = []; postData.params.forEach((param) => { const part = {}; if (param.fileName && !param.value) { includeFS = true; part.body = `fs.createReadStream('${param.fileName}')`; addPostProcessor((code) => code.replace(/'fs\.createReadStream\(\\'(.+)\\'\)'/, "fs.createReadStream('$1')")); } else if (param.value) { part.body = param.value; } if (part.body) { if (param.contentType) { part["content-type"] = param.contentType; } multipart.push(part); } }); push(`req.multipart(${stringifyObject9__default.default(multipart, { indent: opts.indent })});`); blank(); break; } default: if (postData.text) { push(`req.send(${stringifyObject9__default.default(postData.text, { indent: opts.indent })});`); blank(); } } if (includeFS) { unshift("const fs = require('fs');"); } push("req.end(function (res) {"); push("if (res.error) throw new Error(res.error);", 1); blank(); push("console.log(res.body);", 1); push("});"); return join(); } }; // src/targets/node/target.ts var node = { info: { key: "node", title: "Node.js", default: "native", cli: "node %s" }, clientsById: { native: native3, request, unirest: unirest2, axios: axios2, fetch: fetch2 } }; // src/targets/objc/helpers.ts var nsDeclaration = (nsClass, name, parameters, indent) => { const opening = `${nsClass} *${name} = `; const literal = literalRepresentation(parameters, indent ? opening.length : void 0); return `${opening}${literal};`; }; var literalRepresentation = (value, indentation) => { const join = indentation === void 0 ? ", " : `, ${" ".repeat(indentation)}`; switch (Object.prototype.toString.call(value)) { case "[object Number]": return `@${value}`; case "[object Array]": { const valuesRepresentation = value.map((val) => literalRepresentation(val)); return `@[ ${valuesRepresentation.join(join)} ]`; } case "[object Object]": { const keyValuePairs = []; Object.keys(value).forEach((key) => { keyValuePairs.push(`@"${key}": ${literalRepresentation(value[key])}`); }); return `@{ ${keyValuePairs.join(join)} }`; } case "[object Boolean]": return value ? "@YES" : "@NO"; default: if (value === null || value === void 0) { return ""; } return `@"${value.toString().replace(/"/g, '\\"')}"`; } }; // src/targets/objc/nsurlsession/client.ts var nsurlsession = { info: { key: "nsurlsession", title: "NSURLSession", link: "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html", description: "Foundation's NSURLSession request", extname: ".m" }, convert: ({ allHeaders, postData, method, fullUrl }, options) => { const opts = { indent: " ", pretty: true, timeout: 10, ...options }; const { push, join, blank } = new CodeBuilder({ indent: opts.indent }); const req = { hasHeaders: false, hasBody: false }; push("#import "); if (Object.keys(allHeaders).length) { req.hasHeaders = true; blank(); push(nsDeclaration("NSDictionary", "headers", allHeaders, opts.pretty)); } if (postData.text || postData.jsonObj || postData.params) { req.hasBody = true; switch (postData.mimeType) { case "application/x-www-form-urlencoded": if (postData.params?.length) { blank(); const [head, ...tail] = postData.params; push( `NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"${head.name}=${head.value}" dataUsingEncoding:NSUTF8StringEncoding]];` ); tail.forEach(({ name, value }) => { push(`[postData appendData:[@"&${name}=${value}" dataUsingEncoding:NSUTF8StringEncoding]];`); }); } else { req.hasBody = false; } break; case "application/json": if (postData.jsonObj) { push(nsDeclaration("NSDictionary", "parameters", postData.jsonObj, opts.pretty)); blank(); push("NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];"); } break; case "multipart/form-data": push(nsDeclaration("NSArray", "parameters", postData.params || [], opts.pretty)); push(`NSString *boundary = @"${postData.boundary}";`); blank(); push("NSError *error;"); push("NSMutableString *body = [NSMutableString string];"); push("for (NSDictionary *param in parameters) {"); push('[body appendFormat:@"--%@\\r\\n", boundary];', 1); push('if (param[@"fileName"]) {', 1); push( '[body appendFormat:@"Content-Disposition:form-data; name=\\"%@\\"; filename=\\"%@\\"\\r\\n", param[@"name"], param[@"fileName"]];', 2 ); push('[body appendFormat:@"Content-Type: %@\\r\\n\\r\\n", param[@"contentType"]];', 2); push( '[body appendFormat:@"%@", [NSString stringWithContentsOfFile:param[@"fileName"] encoding:NSUTF8StringEncoding error:&error]];', 2 ); push("if (error) {", 2); push('NSLog(@"%@", error);', 3); push("}", 2); push("} else {", 1); push('[body appendFormat:@"Content-Disposition:form-data; name=\\"%@\\"\\r\\n\\r\\n", param[@"name"]];', 2); push('[body appendFormat:@"%@", param[@"value"]];', 2); push("}", 1); push("}"); push('[body appendFormat:@"\\r\\n--%@--\\r\\n", boundary];'); push("NSData *postData = [body dataUsingEncoding:NSUTF8StringEncoding];"); break; default: blank(); push( `NSData *postData = [[NSData alloc] initWithData:[@"${postData.text}" dataUsingEncoding:NSUTF8StringEncoding]];` ); } } blank(); push(`NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"${fullUrl}"]`); push(" cachePolicy:NSURLRequestUseProtocolCachePolicy"); push(` timeoutInterval:${opts.timeout.toFixed(1)}];`); push(`[request setHTTPMethod:@"${method}"];`); if (req.hasHeaders) { push("[request setAllHTTPHeaderFields:headers];"); } if (req.hasBody) { push("[request setHTTPBody:postData];"); } blank(); push("NSURLSession *session = [NSURLSession sharedSession];"); push("NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request"); push( " completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {" ); push(" if (error) {", 1); push(' NSLog(@"%@", error);', 2); push(" } else {", 1); push( " NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;", 2 ); push(' NSLog(@"%@", httpResponse);', 2); push(" }", 1); push(" }];"); push("[dataTask resume];"); return join(); } }; // src/targets/objc/target.ts var objc = { info: { key: "objc", title: "Objective-C", default: "nsurlsession" }, clientsById: { nsurlsession } }; // src/targets/ocaml/cohttp/client.ts var cohttp = { info: { key: "cohttp", title: "CoHTTP", link: "https://github.com/mirage/ocaml-cohttp", description: "Cohttp is a very lightweight HTTP server using Lwt or Async for OCaml", extname: ".ml", installation: "opam install cohttp-lwt-unix cohttp-async" }, convert: ({ fullUrl, allHeaders, postData, method }, options) => { const opts = { indent: " ", ...options }; const methods = ["get", "post", "head", "delete", "patch", "put", "options"]; const { push, blank, join } = new CodeBuilder({ indent: opts.indent }); push("open Cohttp_lwt_unix"); push("open Cohttp"); push("open Lwt"); blank(); push(`let uri = Uri.of_string "${fullUrl}" in`); const headers = Object.keys(allHeaders); if (headers.length === 1) { push( `let headers = Header.add (Header.init ()) "${headers[0]}" "${escapeForDoubleQuotes( allHeaders[headers[0]] )}" in` ); } else if (headers.length > 1) { push("let headers = Header.add_list (Header.init ()) ["); headers.forEach((key) => { push(`("${key}", "${escapeForDoubleQuotes(allHeaders[key])}");`, 1); }); push("] in"); } if (postData.text) { push(`let body = Cohttp_lwt_body.of_string ${JSON.stringify(postData.text)} in`); } blank(); const h = headers.length ? "~headers " : ""; const b = postData.text ? "~body " : ""; const m = methods.includes(method.toLowerCase()) ? `\`${method.toUpperCase()}` : `(Code.method_of_string "${method}")`; push(`Client.call ${h}${b}${m} uri`); push(">>= fun (res, body_stream) ->"); push("(* Do stuff with the result *)", 1); return join(); } }; // src/targets/ocaml/target.ts var ocaml = { info: { key: "ocaml", title: "OCaml", default: "cohttp" }, clientsById: { cohttp } }; // src/targets/php/helpers.ts var convertType = (obj, indent, lastIndent) => { lastIndent = lastIndent || ""; indent = indent || ""; switch (Object.prototype.toString.call(obj)) { case "[object Boolean]": return obj; case "[object Null]": return "null"; case "[object Undefined]": return "null"; case "[object String]": return `'${escapeString(obj, { delimiter: "'", escapeNewlines: false })}'`; case "[object Number]": return obj.toString(); case "[object Array]": { const contents = obj.map((item) => convertType(item, `${indent}${indent}`, indent)).join(`, ${indent}`); return `[ ${indent}${contents} ${lastIndent}]`; } case "[object Object]": { const result = []; for (const i in obj) { if (Object.prototype.hasOwnProperty.call(obj, i)) { result.push(`${convertType(i, indent)} => ${convertType(obj[i], `${indent}${indent}`, indent)}`); } } return `[ ${indent}${result.join(`, ${indent}`)} ${lastIndent}]`; } default: return "null"; } }; var supportedMethods = [ "ACL", "BASELINE_CONTROL", "CHECKIN", "CHECKOUT", "CONNECT", "COPY", "DELETE", "GET", "HEAD", "LABEL", "LOCK", "MERGE", "MKACTIVITY", "MKCOL", "MKWORKSPACE", "MOVE", "OPTIONS", "POST", "PROPFIND", "PROPPATCH", "PUT", "REPORT", "TRACE", "UNCHECKOUT", "UNLOCK", "UPDATE", "VERSION_CONTROL" ]; // src/targets/php/curl/client.ts var curl = { info: { key: "curl", title: "cURL", link: "http://php.net/manual/en/book.curl.php", description: "PHP with ext-curl", extname: ".php" }, convert: ({ uriObj, postData, fullUrl, method, httpVersion, cookies, headersObj }, options = {}) => { const { closingTag = false, indent = " ", maxRedirects = 10, namedErrors = false, noTags = false, shortTags = false, timeout = 30 } = options; const { push, blank, join } = new CodeBuilder({ indent }); if (!noTags) { push(shortTags ? " { if (value !== null && value !== void 0) { curlopts.push(`${name} => ${escape2 ? JSON.stringify(value) : value},`); } }); const curlCookies = cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`); if (curlCookies.length) { curlopts.push(`CURLOPT_COOKIE => "${curlCookies.join("; ")}",`); } const headers = Object.keys(headersObj).sort().map((key) => `"${key}: ${escapeForDoubleQuotes(headersObj[key])}"`); if (headers.length) { curlopts.push("CURLOPT_HTTPHEADER => ["); curlopts.push(headers.join(`, ${indent}${indent}`), 1); curlopts.push("],"); } push(curlopts.join(), 1); push("]);"); blank(); push("$response = curl_exec($curl);"); push("$err = curl_error($curl);"); blank(); push("curl_close($curl);"); blank(); push("if ($err) {"); if (namedErrors) { push('echo array_flip(get_defined_constants(true)["curl"])[$err];', 1); } else { push('echo "cURL Error #:" . $err;', 1); } push("} else {"); push("echo $response;", 1); push("}"); if (!noTags && closingTag) { blank(); push("?>"); } return join(); } }; // src/targets/php/guzzle/client.ts var guzzle = { info: { key: "guzzle", title: "Guzzle", link: "http://docs.guzzlephp.org/en/stable/", description: "PHP with Guzzle", extname: ".php", installation: "composer require guzzlehttp/guzzle" }, convert: ({ postData, fullUrl, method, cookies, headersObj }, options) => { const opts = { closingTag: false, indent: " ", noTags: false, shortTags: false, ...options }; const { push, blank, join } = new CodeBuilder({ indent: opts.indent }); const { code: requestCode, push: requestPush, join: requestJoin } = new CodeBuilder({ indent: opts.indent }); if (!opts.noTags) { push(opts.shortTags ? " ${convertType(postData.paramsObj, opts.indent + opts.indent, opts.indent)},`, 1); break; case "multipart/form-data": { const fields = []; if (postData.params) { postData.params.forEach((param) => { if (param.fileName) { const field = { name: param.name, filename: param.fileName, contents: param.value }; if (param.contentType) { field.headers = { "Content-Type": param.contentType }; } fields.push(field); } else if (param.value) { fields.push({ name: param.name, contents: param.value }); } }); } if (fields.length) { requestPush(`'multipart' => ${convertType(fields, opts.indent + opts.indent, opts.indent)}`, 1); if (hasHeader(headersObj, "content-type")) { if (getHeader(headersObj, "content-type")?.indexOf("boundary")) { const headerName = getHeaderName(headersObj, "content-type"); if (headerName) { delete headersObj[headerName]; } } } } break; } default: if (postData.text) { requestPush(`'body' => ${convertType(postData.text)},`, 1); } } const headers = Object.keys(headersObj).sort().map(function(key) { return `${opts.indent}${opts.indent}'${key}' => '${escapeForSingleQuotes(headersObj[key])}',`; }); const cookieString = cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`).join("; "); if (cookieString.length) { headers.push(`${opts.indent}${opts.indent}'cookie' => '${escapeForSingleQuotes(cookieString)}',`); } if (headers.length) { requestPush("'headers' => [", 1); requestPush(headers.join("\n")); requestPush("],", 1); } push("$client = new \\GuzzleHttp\\Client();"); blank(); if (requestCode.length) { push(`$response = $client->request('${method}', '${fullUrl}', [`); push(requestJoin()); push("]);"); } else { push(`$response = $client->request('${method}', '${fullUrl}');`); } blank(); push("echo $response->getBody();"); if (!opts.noTags && opts.closingTag) { blank(); push("?>"); } return join(); } }; // src/targets/php/http1/client.ts var http1 = { info: { key: "http1", title: "HTTP v1", link: "http://php.net/manual/en/book.http.php", description: "PHP with pecl/http v1", extname: ".php" }, convert: ({ method, url, postData, queryObj, headersObj, cookiesObj }, options = {}) => { const { closingTag = false, indent = " ", noTags = false, shortTags = false } = options; const { push, blank, join } = new CodeBuilder({ indent }); if (!noTags) { push(shortTags ? "setUrl(${convertType(url)});`); if (supportedMethods.includes(method.toUpperCase())) { push(`$request->setMethod(HTTP_METH_${method.toUpperCase()});`); } else { push(`$request->setMethod(HttpRequest::HTTP_METH_${method.toUpperCase()});`); } blank(); if (Object.keys(queryObj).length) { push(`$request->setQueryData(${convertType(queryObj, indent)});`); blank(); } if (Object.keys(headersObj).length) { push(`$request->setHeaders(${convertType(headersObj, indent)});`); blank(); } if (Object.keys(cookiesObj).length) { push(`$request->setCookies(${convertType(cookiesObj, indent)});`); blank(); } switch (postData.mimeType) { case "application/x-www-form-urlencoded": push(`$request->setContentType(${convertType(postData.mimeType)});`); push(`$request->setPostFields(${convertType(postData.paramsObj, indent)});`); blank(); break; case "application/json": push(`$request->setContentType(${convertType(postData.mimeType)});`); push(`$request->setBody(json_encode(${convertType(postData.jsonObj, indent)}));`); blank(); break; default: if (postData.text) { push(`$request->setBody(${convertType(postData.text)});`); blank(); } } push("try {"); push("$response = $request->send();", 1); blank(); push("echo $response->getBody();", 1); push("} catch (HttpException $ex) {"); push("echo $ex;", 1); push("}"); if (!noTags && closingTag) { blank(); push("?>"); } return join(); } }; // src/targets/php/http2/client.ts var http2 = { info: { key: "http2", title: "HTTP v2", link: "http://devel-m6w6.rhcloud.com/mdref/http", description: "PHP with pecl/http v2", extname: ".php" }, convert: ({ postData, headersObj, method, queryObj, cookiesObj, url }, options = {}) => { const { closingTag = false, indent = " ", noTags = false, shortTags = false } = options; const { push, blank, join } = new CodeBuilder({ indent }); let hasBody = false; if (!noTags) { push(shortTags ? "append(new http\\QueryString(${convertType(postData.paramsObj, indent)}));`); blank(); hasBody = true; break; case "multipart/form-data": { if (!postData.params) { break; } const files = []; const fields = {}; postData.params.forEach(({ name, fileName, value, contentType }) => { if (fileName) { files.push({ name, type: contentType, file: fileName, data: value }); return; } if (value) { fields[name] = value; } }); const field = Object.keys(fields).length ? convertType(fields, indent) : "null"; const formValue = files.length ? convertType(files, indent) : "null"; push("$body = new http\\Message\\Body;"); push(`$body->addForm(${field}, ${formValue});`); if (hasHeader(headersObj, "content-type")) { if (getHeader(headersObj, "content-type")?.indexOf("boundary")) { const headerName = getHeaderName(headersObj, "content-type"); if (headerName) { delete headersObj[headerName]; } } } blank(); hasBody = true; break; } case "application/json": push("$body = new http\\Message\\Body;"); push(`$body->append(json_encode(${convertType(postData.jsonObj, indent)}));`); hasBody = true; break; default: if (postData.text) { push("$body = new http\\Message\\Body;"); push(`$body->append(${convertType(postData.text)});`); blank(); hasBody = true; } } push(`$request->setRequestUrl(${convertType(url)});`); push(`$request->setRequestMethod(${convertType(method)});`); if (hasBody) { push("$request->setBody($body);"); blank(); } if (Object.keys(queryObj).length) { push(`$request->setQuery(new http\\QueryString(${convertType(queryObj, indent)}));`); blank(); } if (Object.keys(headersObj).length) { push(`$request->setHeaders(${convertType(headersObj, indent)});`); blank(); } if (Object.keys(cookiesObj).length) { blank(); push(`$client->setCookies(${convertType(cookiesObj, indent)});`); blank(); } push("$client->enqueue($request)->send();"); push("$response = $client->getResponse();"); blank(); push("echo $response->getBody();"); if (!noTags && closingTag) { blank(); push("?>"); } return join(); } }; // src/targets/php/target.ts var php = { info: { key: "php", title: "PHP", default: "curl", cli: "php %s" }, clientsById: { curl, guzzle, http1, http2 } }; // src/targets/powershell/common.ts var generatePowershellConvert = (command) => { const convert = ({ method, headersObj, cookies, uriObj, fullUrl, postData, allHeaders }) => { const { push, join } = new CodeBuilder(); const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; if (!methods.includes(method.toUpperCase())) { return "Method not supported"; } const commandOptions = []; const headers = Object.keys(headersObj); if (headers.length) { push("$headers=@{}"); headers.forEach((key) => { if (key !== "connection") { push(`$headers.Add("${key}", "${escapeString(headersObj[key], { escapeChar: "`" })}")`); } }); commandOptions.push("-Headers $headers"); } if (cookies.length) { push("$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession"); cookies.forEach((cookie) => { push("$cookie = New-Object System.Net.Cookie"); push(`$cookie.Name = '${cookie.name}'`); push(`$cookie.Value = '${cookie.value}'`); push(`$cookie.Domain = '${uriObj.host}'`); push("$session.Cookies.Add($cookie)"); }); commandOptions.push("-WebSession $session"); } if (postData.text) { commandOptions.push( `-ContentType '${escapeString(getHeader(allHeaders, "content-type"), { delimiter: "'", escapeChar: "`" })}'` ); commandOptions.push(`-Body '${postData.text}'`); } push(`$response = ${command} -Uri '${fullUrl}' -Method ${method} ${commandOptions.join(" ")}`.trim()); return join(); }; return convert; }; // src/targets/powershell/restmethod/client.ts var restmethod = { info: { key: "restmethod", title: "Invoke-RestMethod", link: "https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Invoke-RestMethod", description: "Powershell Invoke-RestMethod client", extname: ".ps1" }, convert: generatePowershellConvert("Invoke-RestMethod") }; // src/targets/powershell/webrequest/client.ts var webrequest = { info: { key: "webrequest", title: "Invoke-WebRequest", link: "https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Invoke-WebRequest", description: "Powershell Invoke-WebRequest client", extname: ".ps1" }, convert: generatePowershellConvert("Invoke-WebRequest") }; // src/targets/powershell/target.ts var powershell = { info: { key: "powershell", title: "Powershell", default: "webrequest" }, clientsById: { webrequest, restmethod } }; // src/targets/python/helpers.ts function concatValues(concatType, values, pretty, indentation, indentLevel) { const currentIndent = indentation.repeat(indentLevel); const closingBraceIndent = indentation.repeat(indentLevel - 1); const join = pretty ? `, ${currentIndent}` : ", "; const openingBrace = concatType === "object" ? "{" : "["; const closingBrace = concatType === "object" ? "}" : "]"; if (pretty) { return `${openingBrace} ${currentIndent}${values.join(join)} ${closingBraceIndent}${closingBrace}`; } if (concatType === "object" && values.length > 0) { return `${openingBrace} ${values.join(join)} ${closingBrace}`; } return `${openingBrace}${values.join(join)}${closingBrace}`; } var literalRepresentation2 = (value, opts, indentLevel) => { indentLevel = indentLevel === void 0 ? 1 : indentLevel + 1; switch (Object.prototype.toString.call(value)) { case "[object Number]": return value; case "[object Array]": { let pretty = false; const valuesRepresentation = value.map((v) => { if (Object.prototype.toString.call(v) === "[object Object]") { pretty = Object.keys(v).length > 1; } return literalRepresentation2(v, opts, indentLevel); }); return concatValues("array", valuesRepresentation, pretty, opts.indent, indentLevel); } case "[object Object]": { const keyValuePairs = []; for (const key in value) { keyValuePairs.push(`"${key}": ${literalRepresentation2(value[key], opts, indentLevel)}`); } return concatValues("object", keyValuePairs, opts.pretty && keyValuePairs.length > 1, opts.indent, indentLevel); } case "[object Null]": return "None"; case "[object Boolean]": return value ? "True" : "False"; default: if (value === null || value === void 0) { return ""; } return `"${value.toString().replace(/"/g, '\\"')}"`; } }; // src/targets/python/requests/client.ts var builtInMethods = ["HEAD", "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]; var requests = { info: { key: "requests", title: "Requests", link: "http://docs.python-requests.org/en/latest/api/#requests.request", description: "Requests HTTP library", extname: ".py", installation: "python -m pip install requests" }, convert: ({ fullUrl, postData, allHeaders, method }, options) => { const opts = { indent: " ", pretty: true, ...options }; const { push, blank, join, addPostProcessor } = new CodeBuilder({ indent: opts.indent }); push("import requests"); blank(); push(`url = "${fullUrl}"`); blank(); const headers = allHeaders; let payload = {}; const files = {}; let hasFiles = false; let hasPayload = false; let jsonPayload = false; switch (postData.mimeType) { case "application/json": if (postData.jsonObj) { push(`payload = ${literalRepresentation2(postData.jsonObj, opts)}`); jsonPayload = true; hasPayload = true; } break; case "multipart/form-data": if (!postData.params) { break; } payload = {}; postData.params.forEach((p) => { if (p.fileName) { if (p.contentType) { files[p.name] = `('${p.fileName}', open('${p.fileName}', 'rb'), '${p.contentType}')`; } else { files[p.name] = `('${p.fileName}', open('${p.fileName}', 'rb'))`; } hasFiles = true; } else { payload[p.name] = p.value; hasPayload = true; } }); if (hasFiles) { push(`files = ${literalRepresentation2(files, opts)}`); if (hasPayload) { push(`payload = ${literalRepresentation2(payload, opts)}`); } const headerName = getHeaderName(headers, "content-type"); if (headerName) { delete headers[headerName]; } } else { const nonFilePayload = JSON.stringify(postData.text); if (nonFilePayload) { push(`payload = ${nonFilePayload}`); hasPayload = true; } } addPostProcessor( (code) => code.replace(/"\('(.+)', open\('(.+)', 'rb'\)\)"/g, '("$1", open("$2", "rb"))').replace(/"\('(.+)', open\('(.+)', 'rb'\), '(.+)'\)"/g, '("$1", open("$2", "rb"), "$3")') ); break; default: { if (postData.mimeType === "application/x-www-form-urlencoded" && postData.paramsObj) { push(`payload = ${literalRepresentation2(postData.paramsObj, opts)}`); hasPayload = true; break; } const stringPayload = JSON.stringify(postData.text); if (stringPayload) { push(`payload = ${stringPayload}`); hasPayload = true; } } } const headerCount = Object.keys(headers).length; if (headerCount === 0 && (hasPayload || hasFiles)) { blank(); } else if (headerCount === 1) { Object.keys(headers).forEach((header) => { push(`headers = {"${header}": "${escapeForDoubleQuotes(headers[header])}"}`); blank(); }); } else if (headerCount > 1) { let count = 1; push("headers = {"); Object.keys(headers).forEach((header) => { if (count !== headerCount) { push(`"${header}": "${escapeForDoubleQuotes(headers[header])}",`, 1); } else { push(`"${header}": "${escapeForDoubleQuotes(headers[header])}"`, 1); } count += 1; }); push("}"); blank(); } let request2 = builtInMethods.includes(method) ? `response = requests.${method.toLowerCase()}(url` : `response = requests.request("${method}", url`; if (hasPayload) { if (jsonPayload) { request2 += ", json=payload"; } else { request2 += ", data=payload"; } } if (hasFiles) { request2 += ", files=files"; } if (headerCount > 0) { request2 += ", headers=headers"; } request2 += ")"; push(request2); blank(); push("print(response.text)"); return join(); } }; // src/targets/python/target.ts var python = { info: { key: "python", title: "Python", default: "requests", cli: "python3 %s" }, clientsById: { requests } }; // src/targets/r/httr/client.ts var httr = { info: { key: "httr", title: "httr", link: "https://cran.r-project.org/web/packages/httr/vignettes/quickstart.html", description: "httr: Tools for Working with URLs and HTTP", extname: ".r" }, convert: ({ url, queryObj, queryString, postData, allHeaders, method }) => { const { push, blank, join } = new CodeBuilder(); push("library(httr)"); blank(); push(`url <- "${url}"`); blank(); const qs = queryObj; delete queryObj.key; const queryCount = Object.keys(qs).length; if (queryString.length === 1) { push(`queryString <- list(${Object.keys(qs)} = "${Object.values(qs).toString()}")`); blank(); } else if (queryString.length > 1) { push("queryString <- list("); Object.keys(qs).forEach((query, i) => { if (i !== queryCount - 1) { push(` ${query} = "${qs[query].toString()}",`); } else { push(` ${query} = "${qs[query].toString()}"`); } }); push(")"); blank(); } const payload = JSON.stringify(postData.text); if (payload) { push(`payload <- ${payload}`); blank(); } if (postData.text || postData.jsonObj || postData.params) { switch (postData.mimeType) { case "application/x-www-form-urlencoded": push('encode <- "form"'); blank(); break; case "application/json": push('encode <- "json"'); blank(); break; case "multipart/form-data": push('encode <- "multipart"'); blank(); break; default: push('encode <- "raw"'); blank(); break; } } const cookieHeader = getHeader(allHeaders, "cookie"); const acceptHeader = getHeader(allHeaders, "accept"); const setCookies = cookieHeader ? `set_cookies(\`${String(cookieHeader).replace(/;/g, '", `').replace(/` /g, "`").replace(/[=]/g, '` = "')}")` : void 0; const setAccept = acceptHeader ? `accept("${escapeForDoubleQuotes(acceptHeader)}")` : void 0; const setContentType = `content_type("${escapeForDoubleQuotes(postData.mimeType)}")`; const otherHeaders = Object.entries(allHeaders).filter(([key]) => !["cookie", "accept", "content-type"].includes(key.toLowerCase())).map(([key, value]) => `'${key}' = '${escapeForSingleQuotes(value)}'`).join(", "); const setHeaders = otherHeaders ? `add_headers(${otherHeaders})` : void 0; let request2 = `response <- VERB("${method}", url`; if (payload) { request2 += ", body = payload"; } if (queryString.length) { request2 += ", query = queryString"; } const headerAdditions = [setHeaders, setContentType, setAccept, setCookies].filter((x) => !!x).join(", "); if (headerAdditions) { request2 += `, ${headerAdditions}`; } if (postData.text || postData.jsonObj || postData.params) { request2 += ", encode = encode"; } request2 += ")"; push(request2); blank(); push('content(response, "text")'); return join(); } }; // src/targets/r/target.ts var r = { info: { key: "r", title: "R", default: "httr" }, clientsById: { httr } }; // src/targets/ruby/native/client.ts var native4 = { info: { key: "native", title: "net::http", link: "http://ruby-doc.org/stdlib-2.2.1/libdoc/net/http/rdoc/Net/HTTP.html", description: "Ruby HTTP client", extname: ".rb" }, convert: ({ uriObj, method: rawMethod, fullUrl, postData, allHeaders }) => { const { push, blank, join } = new CodeBuilder(); push("require 'uri'"); push("require 'net/http'"); blank(); const method = rawMethod.toUpperCase(); const methods = [ "GET", "POST", "HEAD", "DELETE", "PATCH", "PUT", "OPTIONS", "COPY", "LOCK", "UNLOCK", "MOVE", "TRACE" ]; const capMethod = method.charAt(0) + method.substring(1).toLowerCase(); if (!methods.includes(method)) { push(`class Net::HTTP::${capMethod} < Net::HTTPRequest`); push(` METHOD = '${method.toUpperCase()}'`); push(` REQUEST_HAS_BODY = '${postData.text ? "true" : "false"}'`); push(" RESPONSE_HAS_BODY = true"); push("end"); blank(); } push(`url = URI("${fullUrl}")`); blank(); push("http = Net::HTTP.new(url.host, url.port)"); if (uriObj.protocol === "https:") { push("http.use_ssl = true"); } blank(); push(`request = Net::HTTP::${capMethod}.new(url)`); const headers = Object.keys(allHeaders); if (headers.length) { headers.forEach((key) => { push(`request["${key}"] = '${escapeForSingleQuotes(allHeaders[key])}'`); }); } if (postData.text) { push(`request.body = ${JSON.stringify(postData.text)}`); } blank(); push("response = http.request(request)"); push("puts response.read_body"); return join(); } }; // src/targets/ruby/target.ts var ruby = { info: { key: "ruby", title: "Ruby", default: "native" }, clientsById: { native: native4 } }; // src/helpers/shell.ts var quote = (value = "") => { const safe = /^[a-z0-9-_/.@%^=:]+$/i; const isShellSafe = safe.test(value); if (isShellSafe) { return value; } return `'${value.replace(/'/g, "'\\''")}'`; }; var escape = (value) => value.replace(/\r/g, "\\r").replace(/\n/g, "\\n"); // src/targets/shell/curl/client.ts var params = { "http1.0": "0", "url ": "", cookie: "b", data: "d", form: "F", globoff: "g", header: "H", insecure: "k", request: "X" }; var getArg = (short) => (longName) => { if (short) { const shortName = params[longName]; if (!shortName) { return ""; } return `-${shortName}`; } return `--${longName}`; }; var curl2 = { info: { key: "curl", title: "cURL", link: "http://curl.haxx.se/", description: "cURL is a command line tool and library for transferring data with URL syntax", extname: ".sh" }, convert: ({ fullUrl, method, httpVersion, headersObj, allHeaders, postData }, options = {}) => { const { indent = " ", short = false, binary = false, globOff = false } = options; const indentJSON = " "; const { push, join } = new CodeBuilder({ ...typeof indent === "string" ? { indent } : {}, join: indent !== false ? ` \\ ${indent}` : " " }); const arg = getArg(short); let formattedUrl = quote(fullUrl); push(`curl ${arg("request")} ${method}`); if (globOff) { formattedUrl = unescape(formattedUrl); push(arg("globoff")); } push(`${arg("url ")}${formattedUrl}`); if (httpVersion === "HTTP/1.0") { push(arg("http1.0")); } if (getHeader(allHeaders, "accept-encoding")) { push("--compressed"); } if (postData.mimeType === "multipart/form-data") { const contentTypeHeaderName = getHeaderName(headersObj, "content-type"); if (contentTypeHeaderName) { const contentTypeHeader = headersObj[contentTypeHeaderName]; if (contentTypeHeaderName && contentTypeHeader) { const noBoundary = String(contentTypeHeader).replace(/; boundary.+?(?=(;|$))/, ""); headersObj[contentTypeHeaderName] = noBoundary; allHeaders[contentTypeHeaderName] = noBoundary; } } } Object.keys(headersObj).sort().forEach((key) => { const header = `${key}: ${headersObj[key]}`; push(`${arg("header")} ${quote(header)}`); }); if (allHeaders.cookie) { push(`${arg("cookie")} ${quote(allHeaders.cookie)}`); } switch (postData.mimeType) { case "multipart/form-data": postData.params?.forEach((param) => { let post = ""; if (param.fileName) { post = `${param.name}='@${param.fileName}'`; } else { post = quote(`${param.name}=${param.value}`); } push(`${arg("form")} ${post}`); }); break; case "application/x-www-form-urlencoded": if (postData.params) { postData.params.forEach((param) => { const unencoded = param.name; const encoded = encodeURIComponent(param.name); const needsEncoding = encoded !== unencoded; const name = needsEncoding ? encoded : unencoded; const flag = binary ? "--data-binary" : needsEncoding ? "--data-urlencode" : arg("data"); push(`${flag} ${quote(`${name}=${param.value}`)}`); }); } else { push(`${binary ? "--data-binary" : arg("data")} ${quote(postData.text)}`); } break; default: if (!postData.text) { break; } let builtPayload = false; if (isMimeTypeJSON(postData.mimeType)) { if (postData.text.length > 20) { try { const jsonPayload = JSON.parse(postData.text); builtPayload = true; if (postData.text.indexOf("'") > 0) { push( `${binary ? "--data-binary" : arg("data")} @- < { const opts = { body: false, cert: false, headers: false, indent: " ", pretty: false, print: false, queryParams: false, short: false, style: false, timeout: false, verbose: false, verify: false, ...options }; const { push, join, unshift } = new CodeBuilder({ indent: opts.indent, // @ts-expect-error SEEMS LEGIT join: opts.indent !== false ? ` \\ ${opts.indent}` : " " }); let raw = false; const flags = []; if (opts.headers) { flags.push(opts.short ? "-h" : "--headers"); } if (opts.body) { flags.push(opts.short ? "-b" : "--body"); } if (opts.verbose) { flags.push(opts.short ? "-v" : "--verbose"); } if (opts.print) { flags.push(`${opts.short ? "-p" : "--print"}=${opts.print}`); } if (opts.verify) { flags.push(`--verify=${opts.verify}`); } if (opts.cert) { flags.push(`--cert=${opts.cert}`); } if (opts.pretty) { flags.push(`--pretty=${opts.pretty}`); } if (opts.style) { flags.push(`--style=${opts.style}`); } if (opts.timeout) { flags.push(`--timeout=${opts.timeout}`); } if (opts.queryParams) { Object.keys(queryObj).forEach((name) => { const value = queryObj[name]; if (Array.isArray(value)) { value.forEach((val) => { push(`${name}==${quote(val)}`); }); } else { push(`${name}==${quote(value)}`); } }); } Object.keys(allHeaders).sort().forEach((key) => { push(`${key}:${quote(allHeaders[key])}`); }); if (postData.mimeType === "application/x-www-form-urlencoded") { if (postData.params && postData.params.length) { flags.push(opts.short ? "-f" : "--form"); postData.params.forEach((param) => { push(`${param.name}=${quote(param.value)}`); }); } } else { raw = true; } const cliFlags = flags.length ? `${flags.join(" ")} ` : ""; url = quote(opts.queryParams ? url : fullUrl); unshift(`http ${cliFlags}${method} ${url}`); if (raw && postData.text) { const postDataText = quote(postData.text); unshift(`echo ${postDataText} | `); } return join(); } }; // src/targets/shell/wget/client.ts var wget = { info: { key: "wget", title: "Wget", link: "https://www.gnu.org/software/wget/", description: "a free software package for retrieving files using HTTP, HTTPS", extname: ".sh" }, convert: ({ method, postData, allHeaders, fullUrl }, options) => { const opts = { indent: " ", short: false, verbose: false, ...options }; const { push, join } = new CodeBuilder({ ...typeof opts.indent === "string" ? { indent: opts.indent } : {}, join: opts.indent !== false ? ` \\ ${opts.indent}` : " " }); if (opts.verbose) { push(`wget ${opts.short ? "-v" : "--verbose"}`); } else { push(`wget ${opts.short ? "-q" : "--quiet"}`); } push(`--method ${quote(method)}`); Object.keys(allHeaders).forEach((key) => { const header = `${key}: ${allHeaders[key]}`; push(`--header ${quote(header)}`); }); if (postData.text) { push(`--body-data ${escape(quote(postData.text))}`); } push(opts.short ? "-O" : "--output-document"); push(`- ${quote(fullUrl)}`); return join(); } }; // src/targets/shell/target.ts var shell = { info: { key: "shell", title: "Shell", default: "curl", cli: "%s" }, clientsById: { curl: curl2, httpie, wget } }; // src/targets/swift/helpers.ts var buildString = (length, str) => str.repeat(length); var concatArray = (arr, pretty, indentation, indentLevel) => { const currentIndent = buildString(indentLevel, indentation); const closingBraceIndent = buildString(indentLevel - 1, indentation); const join = pretty ? `, ${currentIndent}` : ", "; if (pretty) { return `[ ${currentIndent}${arr.join(join)} ${closingBraceIndent}]`; } return `[${arr.join(join)}]`; }; var literalDeclaration = (name, parameters, opts) => `let ${name} = ${literalRepresentation3(parameters, opts)}`; var literalRepresentation3 = (value, opts, indentLevel) => { indentLevel = indentLevel === void 0 ? 1 : indentLevel + 1; switch (Object.prototype.toString.call(value)) { case "[object Number]": return value; case "[object Array]": { let pretty = false; const valuesRepresentation = value.map((v) => { if (Object.prototype.toString.call(v) === "[object Object]") { pretty = Object.keys(v).length > 1; } return literalRepresentation3(v, opts, indentLevel); }); return concatArray(valuesRepresentation, pretty, opts.indent, indentLevel); } case "[object Object]": { const keyValuePairs = []; for (const key in value) { keyValuePairs.push(`"${key}": ${literalRepresentation3(value[key], opts, indentLevel)}`); } return concatArray( keyValuePairs, // @ts-expect-error needs better types opts.pretty && keyValuePairs.length > 1, // @ts-expect-error needs better types opts.indent, indentLevel ); } case "[object Boolean]": return value.toString(); default: if (value === null || value === void 0) { return "nil"; } return `"${value.toString().replace(/"/g, '\\"')}"`; } }; // src/targets/swift/urlsession/client.ts var urlsession = { info: { key: "urlsession", title: "URLSession", link: "https://developer.apple.com/documentation/foundation/urlsession", description: "Foundation's URLSession request", extname: ".swift" }, convert: ({ allHeaders, postData, uriObj, queryObj, method }, options) => { const opts = { indent: " ", pretty: true, timeout: 10, ...options }; const { push, blank, join } = new CodeBuilder({ indent: opts.indent }); push("import Foundation"); blank(); const hasBody = postData.text || postData.jsonObj || postData.params; if (hasBody) { switch (postData.mimeType) { case "application/x-www-form-urlencoded": if (postData.params?.length) { const parameters = postData.params.map((p) => `"${p.name}": "${p.value}"`); if (opts.pretty) { push("let parameters = ["); parameters.forEach((param) => push(`${param},`, 1)); push("]"); } else { push(`let parameters = [${parameters.join(", ")}]`); } push('let joinedParameters = parameters.map { "\\($0.key)=\\($0.value)" }.joined(separator: "&")'); push("let postData = Data(joinedParameters.utf8)"); blank(); } break; case "application/json": if (postData.jsonObj) { push(`${literalDeclaration("parameters", postData.jsonObj, opts)} as [String : Any?]`); blank(); push("let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])"); blank(); } break; case "multipart/form-data": push(literalDeclaration("parameters", postData.params, opts)); blank(); push(`let boundary = "${postData.boundary}"`); blank(); push('var body = ""'); push("for param in parameters {"); push('let paramName = param["name"]!', 1); push('body += "--\\(boundary)\\r\\n"', 1); push('body += "Content-Disposition:form-data; name=\\"\\(paramName)\\""', 1); push('if let filename = param["fileName"] {', 1); push('let contentType = param["contentType"]!', 2); push("let fileContent = try String(contentsOfFile: filename, encoding: .utf8)", 2); push('body += "; filename=\\"\\(filename)\\"\\r\\n"', 2); push('body += "Content-Type: \\(contentType)\\r\\n\\r\\n"', 2); push("body += fileContent", 2); push('} else if let paramValue = param["value"] {', 1); push('body += "\\r\\n\\r\\n\\(paramValue)"', 2); push("}", 1); push("}"); blank(); push("let postData = Data(body.utf8)"); blank(); break; default: push(`let postData = Data("${postData.text}".utf8)`); blank(); } } push(`let url = URL(string: "${uriObj.href}")!`); const queries = queryObj ? Object.entries(queryObj) : []; if (queries.length < 1) { push("var request = URLRequest(url: url)"); } else { push("var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!"); push("let queryItems: [URLQueryItem] = ["); queries.forEach((query) => { const key = query[0]; const value = query[1]; switch (Object.prototype.toString.call(value)) { case "[object String]": push(`URLQueryItem(name: "${key}", value: "${value}"),`, 1); break; case "[object Array]": value.forEach((val) => { push(`URLQueryItem(name: "${key}", value: "${val}"),`, 1); }); break; } }); push("]"); push("components.queryItems = components.queryItems.map { $0 + queryItems } ?? queryItems"); blank(); push("var request = URLRequest(url: components.url!)"); } push(`request.httpMethod = "${method}"`); push(`request.timeoutInterval = ${opts.timeout}`); if (Object.keys(allHeaders).length) { push(`request.allHTTPHeaderFields = ${literalRepresentation3(allHeaders, opts)}`); } if (hasBody) { push("request.httpBody = postData"); } blank(); push("let (data, _) = try await URLSession.shared.data(for: request)"); push("print(String(decoding: data, as: UTF8.self))"); return join(); } }; // src/targets/swift/target.ts var swift = { info: { key: "swift", title: "Swift", default: "urlsession" }, clientsById: { urlsession } }; // src/targets/index.ts var targets = { c, clojure, csharp, go, http, java, javascript, json, kotlin, node, objc, ocaml, php, powershell, python, r, ruby, shell, swift }; var isTarget = (target) => { if (typeof target !== "object" || target === null || Array.isArray(target)) { const got = target === null ? "null" : Array.isArray(target) ? "array" : typeof target; throw new Error(`you tried to add a target which is not an object, got type: "${got}"`); } if (!Object.prototype.hasOwnProperty.call(target, "info")) { throw new Error("targets must contain an `info` object"); } if (!Object.prototype.hasOwnProperty.call(target.info, "key")) { throw new Error("targets must have an `info` object with the property `key`"); } if (!target.info.key) { throw new Error("target key must be a unique string"); } if (Object.prototype.hasOwnProperty.call(targets, target.info.key)) { throw new Error(`a target already exists with this key, \`${target.info.key}\``); } if (!Object.prototype.hasOwnProperty.call(target.info, "title")) { throw new Error("targets must have an `info` object with the property `title`"); } if (!target.info.title) { throw new Error("target title must be a non-zero-length string"); } if (!Object.prototype.hasOwnProperty.call(target, "clientsById") || !target.clientsById || Object.keys(target.clientsById).length === 0) { throw new Error( `No clients provided in target ${target.info.key}. You must provide the property \`clientsById\` containg your clients.` ); } if (!Object.prototype.hasOwnProperty.call(target.info, "default")) { throw new Error("targets must have an `info` object with the property `default`"); } if (!Object.prototype.hasOwnProperty.call(target.clientsById, target.info.default)) { throw new Error( `target ${target.info.key} is configured with a default client ${target.info.default}, but no such client was found in the property \`clientsById\` (found ${JSON.stringify( Object.keys(target.clientsById) )})` ); } Object.values(target.clientsById).forEach(isClient); return true; }; var addTarget = (target) => { if (!isTarget(target)) ; targets[target.info.key] = target; }; var isClient = (client) => { if (!client) { throw new Error("clients must be objects"); } if (!Object.prototype.hasOwnProperty.call(client, "info")) { throw new Error("targets client must contain an `info` object"); } if (!Object.prototype.hasOwnProperty.call(client.info, "key")) { throw new Error("targets client must have an `info` object with property `key`"); } if (!client.info.key) { throw new Error("client.info.key must contain an identifier unique to this target"); } if (!Object.prototype.hasOwnProperty.call(client.info, "title")) { throw new Error("targets client must have an `info` object with property `title`"); } if (!Object.prototype.hasOwnProperty.call(client.info, "description")) { throw new Error("targets client must have an `info` object with property `description`"); } if (!Object.prototype.hasOwnProperty.call(client.info, "link")) { throw new Error("targets client must have an `info` object with property `link`"); } if (!Object.prototype.hasOwnProperty.call(client.info, "extname")) { throw new Error("targets client must have an `info` object with the property `extname`"); } if (!Object.prototype.hasOwnProperty.call(client, "convert") || typeof client.convert !== "function") { throw new Error("targets client must have a `convert` property containing a conversion function"); } return true; }; var addClientPlugin = (plugin) => { addTargetClient(plugin.target, plugin.client); }; var addTargetClient = (targetId, client) => { if (!isClient(client)) ; if (!Object.prototype.hasOwnProperty.call(targets, targetId)) { throw new Error(`Sorry, but no ${targetId} target exists to add clients to`); } if (Object.prototype.hasOwnProperty.call(targets[targetId], client.info.key)) { throw new Error( `the target ${targetId} already has a client with the key ${client.info.key}, please use a different key` ); } targets[targetId].clientsById[client.info.key] = client; }; // src/helpers/utils.ts var availableTargets = () => Object.keys(targets).map((targetId) => ({ ...targets[targetId].info, clients: Object.keys(targets[targetId].clientsById).map( (clientId) => targets[targetId].clientsById[clientId].info ) })); var extname = (targetId, clientId) => { const target = targets[targetId]; if (!target) { return ""; } return target.clientsById[clientId]?.info.extname || ""; }; // src/index.ts var isHarEntry = (value) => typeof value === "object" && "log" in value && typeof value.log === "object" && "entries" in value.log && Array.isArray(value.log.entries); var HTTPSnippet = class { constructor(input, opts = {}) { this.initCalled = false; this.entries = []; this.requests = []; this.options = {}; this.options = { harIsAlreadyEncoded: false, ...opts }; this.requests = []; if (isHarEntry(input)) { this.entries = input.log.entries; } else { this.entries = [ { request: input } ]; } } init() { this.initCalled = true; this.requests = this.entries.map(({ request: request2 }) => { const req = { bodySize: 0, headersSize: 0, headers: [], cookies: [], httpVersion: "HTTP/1.1", queryString: [], postData: { mimeType: request2.postData?.mimeType || "application/octet-stream" }, ...request2 }; if (req.postData && !req.postData.mimeType) { req.postData.mimeType = "application/octet-stream"; } return this.prepare(req, this.options); }); return this; } prepare(harRequest, options) { const request2 = { ...harRequest, fullUrl: "", uriObj: {}, queryObj: {}, headersObj: {}, cookiesObj: {}, allHeaders: {} }; if (request2.queryString && request2.queryString.length) { request2.queryObj = request2.queryString.reduce(reducer, {}); } if (request2.headers && request2.headers.length) { const http2VersionRegex = /^HTTP\/2/; request2.headersObj = request2.headers.reduce((accumulator, { name, value }) => { const headerName = http2VersionRegex.exec(request2.httpVersion) ? name.toLocaleLowerCase() : name; return { ...accumulator, [headerName]: value }; }, {}); } if (request2.cookies && request2.cookies.length) { request2.cookiesObj = request2.cookies.reduceRight( (accumulator, { name, value }) => ({ ...accumulator, [name]: value }), {} ); } const cookies = request2.cookies?.map(({ name, value }) => { if (options.harIsAlreadyEncoded) { return `${name}=${value}`; } return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`; }); if (cookies?.length) { request2.allHeaders.cookie = cookies.join("; "); } switch (request2.postData.mimeType) { case "multipart/mixed": case "multipart/related": case "multipart/form-data": case "multipart/alternative": request2.postData.text = ""; request2.postData.mimeType = "multipart/form-data"; if (request2.postData?.params) { const boundary = "---011000010111000001101001"; const carriage = `${boundary}--`; const rn = "\r\n"; const escape2 = (str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22"); const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, "\r\n"); const payload = [`--${boundary}`]; request2.postData?.params.forEach((param, i) => { const name = param.name; const value = param.value || ""; const filename = param.fileName || null; const contentType = param.contentType || "application/octet-stream"; if (filename) { payload.push( `Content-Disposition: form-data; name="${escape2(normalizeLinefeeds(name))}"; filename="${filename}"` ); payload.push(`Content-Type: ${contentType}`); } else { payload.push(`Content-Disposition: form-data; name="${escape2(normalizeLinefeeds(name))}"`); } payload.push(""); payload.push(normalizeLinefeeds(value)); if (i !== request2.postData.params.length - 1) { payload.push(`--${boundary}`); } }); payload.push(`--${carriage}`); request2.postData.boundary = boundary; request2.postData.text = payload.join(rn); const contentTypeHeader = getHeaderName(request2.headersObj, "content-type") || "content-type"; request2.headersObj[contentTypeHeader] = `multipart/form-data; boundary=${boundary}`; } break; case "application/x-www-form-urlencoded": if (!request2.postData.params) { request2.postData.text = ""; } else { request2.postData.paramsObj = request2.postData.params.reduce(reducer, {}); request2.postData.text = qs.stringify(request2.postData.paramsObj); } break; case "text/json": case "text/x-json": case "application/json": case "application/x-json": request2.postData.mimeType = "application/json"; if (request2.postData.text) { try { request2.postData.jsonObj = JSON.parse(request2.postData.text); } catch (e) { request2.postData.mimeType = "text/plain"; } } break; } const allHeaders = { ...request2.allHeaders, ...request2.headersObj }; const urlWithParsedQuery = url.parse(request2.url, true, true); request2.queryObj = { ...request2.queryObj, ...urlWithParsedQuery.query }; let search; if (options.harIsAlreadyEncoded) { search = qs.stringify(request2.queryObj, { encode: false, indices: false }); } else { search = qs.stringify(request2.queryObj, { indices: false }); } const uriObj = { ...urlWithParsedQuery, query: request2.queryObj, search, path: search ? `${urlWithParsedQuery.pathname}?${search}` : urlWithParsedQuery.pathname }; const url$1 = url.format({ ...urlWithParsedQuery, query: null, search: null }); const fullUrl = url.format({ ...urlWithParsedQuery, ...uriObj }); return { ...request2, allHeaders, fullUrl, url: url$1, uriObj }; } convert(targetId, clientId, options) { if (!this.initCalled) { this.init(); } if (!options && clientId) { options = clientId; } const target = targets[targetId]; if (!target) { return false; } const { convert } = target.clientsById[clientId || target.info.default]; const results = this.requests.map((request2) => convert(request2, options)); return results; } }; /*! formdata-polyfill. MIT License. Jimmy Wärting */ exports.HTTPSnippet = HTTPSnippet; exports.addClientPlugin = addClientPlugin; exports.addTarget = addTarget; exports.addTargetClient = addTargetClient; exports.availableTargets = availableTargets; exports.extname = extname; //# sourceMappingURL=out.js.map //# sourceMappingURL=index.cjs.map