UNPKG

httpsnippet-lite

Version:

HTTP Request snippet generator for *most* languages

170 lines (169 loc) 7.55 kB
"use strict"; /** * @description * * HTTP code snippet generator for the Shell using cURL. * * @author * @AhmadNassri * * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.curl = void 0; const code_builder_js_1 = require("../../../helpers/code-builder.js"); const headers_js_1 = require("../../../helpers/headers.js"); const shell_js_1 = require("../../../helpers/shell.js"); /** * This is a const record with keys that correspond to the long names and values that correspond to the short names for cURL arguments. */ const params = { 'http1.0': '0', 'url ': '', cookie: 'b', data: 'd', form: 'F', globoff: 'g', header: 'H', insecure: 'k', request: 'X', }; const getArg = (short) => (longName) => { if (short) { const shortName = params[longName]; if (!shortName) { return ''; } return `-${shortName}`; } return `--${longName}`; }; exports.curl = { 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', }, convert: ({ fullUrl, method, httpVersion, headersObj, allHeaders, postData }, options = {}) => { var _a; const { binary = false, globOff = false, indent = ' ', insecureSkipVerify = false, prettifyJson = false, short = false, } = options; const { push, join } = new code_builder_js_1.CodeBuilder({ ...(typeof indent === 'string' ? { indent: indent } : {}), join: indent !== false ? ` \\\n${indent}` : ' ', }); const arg = getArg(short); let formattedUrl = (0, shell_js_1.quote)(fullUrl); push(`curl ${arg('request')} ${method}`); if (globOff) { formattedUrl = unescape(formattedUrl); push(arg('globoff')); } push(`${arg('url ')}${formattedUrl}`); if (insecureSkipVerify) { push(arg('insecure')); } if (httpVersion === 'HTTP/1.0') { push(arg('http1.0')); } if ((0, headers_js_1.getHeader)(allHeaders, 'accept-encoding')) { // note: there is no shorthand for this cURL option push('--compressed'); } // if multipart form data, we want to remove the boundary if ((postData === null || postData === void 0 ? void 0 : postData.mimeType) === 'multipart/form-data') { const contentTypeHeaderName = (0, headers_js_1.getHeaderName)(headersObj, 'content-type'); if (contentTypeHeaderName) { const contentTypeHeader = headersObj[contentTypeHeaderName]; if (contentTypeHeaderName && contentTypeHeader) { // remove the leading semi colon and boundary // up to the next semi colon or the end of string // @ts-expect-error it is a reality that the headersObj can have values which are string arrays. This is a genuine bug that this case isn't handled or tested. It is, however tested in `reducer.test.ts`. Go check that out to see more. const noBoundary = contentTypeHeader.replace(/; boundary.+?(?=(;|$))/, ''); // replace the content-type header with no boundary in both headersObj and allHeaders headersObj[contentTypeHeaderName] = noBoundary; allHeaders[contentTypeHeaderName] = noBoundary; } } } // construct headers Object.keys(headersObj) .sort() .forEach(key => { const header = `${key}: ${headersObj[key]}`; push(`${arg('header')} ${(0, shell_js_1.quote)(header)}`); }); if (allHeaders.cookie) { push(`${arg('cookie')} ${(0, shell_js_1.quote)(allHeaders.cookie)}`); } // construct post params switch (postData === null || postData === void 0 ? void 0 : postData.mimeType) { case 'multipart/form-data': (_a = postData.params) === null || _a === void 0 ? void 0 : _a.forEach(param => { let post = ''; if (param.fileName) { post = `${param.name}=@${param.fileName}`; } else { post = `${param.name}=${param.value}`; } push(`${arg('form')} ${(0, shell_js_1.quote)(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' : `--data${needsEncoding ? '-urlencode' : ''}`; push(`${flag} ${(0, shell_js_1.quote)(`${name}=${param.value}`)}`); }); } else { push(`${binary ? '--data-binary' : arg('data')} ${(0, shell_js_1.quote)(postData.text)}`); } break; default: { if (!postData) { break; } // raw request body if (!postData.text) { break; } const flag = binary ? '--data-binary' : arg('data'); let builtPayload = false; // If we're dealing with a JSON variant, and our payload is JSON let's make it look a little nicer. if ((0, headers_js_1.isMimeTypeJSON)(postData.mimeType)) { // If our postData is less than 20 characters, let's keep it all on one line so as to not make the snippet overly lengthy. const couldBeJSON = postData.text.length > 2; if (couldBeJSON && prettifyJson) { try { const jsonPayload = JSON.parse(postData.text); // If the JSON object has a single quote we should prepare it inside of a HEREDOC because the single quote in something like `string's` can't be escaped when used with `--data`. // // Basically this boils down to `--data @- <<EOF...EOF` vs `--data '...'`. builtPayload = true; const payload = JSON.stringify(jsonPayload, undefined, indent); if (postData.text.indexOf("'") > 0) { push(`${flag} @- <<EOF\n${payload}\nEOF`); } else { push(`${flag} '\n${payload}\n'`); } } catch (err) { // no-op } } } if (!builtPayload) { push(`${flag} ${(0, shell_js_1.quote)(postData.text)}`); } } } return join(); }, };