UNPKG

insomnia-importers

Version:

Various data importers for Insomnia

288 lines 9.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convert = exports.description = exports.name = exports.id = void 0; const shell_quote_1 = require("shell-quote"); const url_1 = require("url"); exports.id = 'curl'; exports.name = 'cURL'; exports.description = 'cURL command line tool'; let requestCount = 1; const SUPPORTED_ARGS = [ 'url', 'u', 'user', 'header', 'H', 'cookie', 'b', 'get', 'G', 'd', 'data', 'data-raw', 'data-urlencode', 'data-binary', 'data-ascii', 'form', 'F', 'request', 'X', ]; const importCommand = (parseEntries) => { // ~~~~~~~~~~~~~~~~~~~~~ // // Collect all the flags // // ~~~~~~~~~~~~~~~~~~~~~ // const pairsByName = {}; const singletons = []; // Start at 1 so we can skip the ^curl part for (let i = 1; i < parseEntries.length; i++) { const parseEntry = parseEntries[i]; if (typeof parseEntry === 'string' && parseEntry.match(/^-{1,2}[\w-]+/)) { const isSingleDash = parseEntry[0] === '-' && parseEntry[1] !== '-'; let name = parseEntry.replace(/^-{1,2}/, ''); if (!SUPPORTED_ARGS.includes(name)) { continue; } let value; const nextEntry = parseEntries[i + 1]; if (isSingleDash && name.length > 1) { // Handle squished arguments like -XPOST value = name.slice(1); name = name.slice(0, 1); } else if (typeof nextEntry === 'string' && !nextEntry.startsWith('-')) { // Next arg is not a flag, so assign it as the value value = nextEntry; i++; // Skip next one } else { value = true; } if (!pairsByName[name]) { pairsByName[name] = [value]; } else { pairsByName[name].push(value); } } else if (parseEntry) { singletons.push(parseEntry); } } // ~~~~~~~~~~~~~~~~~ // // Build the request // // ~~~~~~~~~~~~~~~~~ // /// /////// Url & parameters ////////// let parameters = []; let url = ''; try { const urlValue = getPairValue(pairsByName, singletons[0] || '', ['url']); const { searchParams, href, search } = new url_1.URL(urlValue); parameters = Array.from(searchParams.entries()).map(([name, value]) => ({ name, value, disabled: false, })); url = href.replace(search, '').replace(/\/$/, ''); } catch (error) { } /// /////// Authentication ////////// const [username, password] = getPairValue(pairsByName, '', [ 'u', 'user', ]).split(/:(.*)$/); const authentication = username ? { username: username.trim(), password: password.trim(), } : {}; /// /////// Headers ////////// const headers = [ ...(pairsByName.header || []), ...(pairsByName.H || []), ].map(header => { const [name, value] = header.split(/:(.*)$/); return { name: name.trim(), value: value.trim(), }; }); /// /////// Cookies ////////// const cookieHeaderValue = [ ...(pairsByName.cookie || []), ...(pairsByName.b || []), ] .map(str => { const name = str.split('=', 1)[0]; const value = str.replace(`${name}=`, ''); return `${name}=${value}`; }) .join('; '); // Convert cookie value to header const existingCookieHeader = headers.find(header => header.name.toLowerCase() === 'cookie'); if (cookieHeaderValue && existingCookieHeader) { // Has existing cookie header, so let's update it existingCookieHeader.value += `; ${cookieHeaderValue}`; } else if (cookieHeaderValue) { // No existing cookie header, so let's make a new one headers.push({ name: 'Cookie', value: cookieHeaderValue, }); } /// /////// Body (Text or Blob) ////////// let textBodyParams = []; const paramNames = [ 'd', 'data', 'data-raw', 'data-urlencode', 'data-binary', 'data-ascii', ]; for (const paramName of paramNames) { const pair = pairsByName[paramName]; if (pair && pair.length) { textBodyParams = textBodyParams.concat(paramName === 'data-urlencode' ? pair.map(item => encodeURIComponent(item)) : pair); } } // join params to make body const textBody = textBodyParams.join('&'); const contentTypeHeader = headers.find(header => header.name.toLowerCase() === 'content-type'); const mimeType = contentTypeHeader ? contentTypeHeader.value.split(';')[0] : null; /// /////// Body (Multipart Form Data) ////////// const formDataParams = [ ...(pairsByName.form || []), ...(pairsByName.F || []), ].map(str => { const [name, value] = str.split('='); const item = { name, }; if (value.indexOf('@') === 0) { item.fileName = value.slice(1); item.type = 'file'; } else { item.value = value; item.type = 'text'; } return item; }); /// /////// Body ////////// const body = mimeType ? { mimeType } : {}; const bodyAsGET = getPairValue(pairsByName, false, ['G', 'get']); if (textBody && bodyAsGET) { const bodyParams = textBody.split('&').map(v => { const [name, value] = v.split('='); return { name: name || '', value: value || '', }; }); parameters.push(...bodyParams); } else if (textBody && mimeType === 'application/x-www-form-urlencoded') { body.params = textBody.split('&').map(v => { const [name, value] = v.split('='); return { name: decodeURIComponent(name || ''), value: decodeURIComponent(value || ''), }; }); } else if (textBody) { body.text = textBody; body.mimeType = mimeType || ''; } else if (formDataParams.length) { body.params = formDataParams; body.mimeType = mimeType || 'multipart/form-data'; } /// /////// Method ////////// let method = getPairValue(pairsByName, '__UNSET__', [ 'X', 'request', ]).toUpperCase(); if (method === '__UNSET__') { method = body.text || body.params ? 'POST' : 'GET'; } const count = requestCount++; return { _id: `__REQ_${count}__`, _type: 'request', parentId: '__WORKSPACE_ID__', name: url || `cURL Import ${count}`, parameters, url, method, headers, authentication, body, }; }; const getPairValue = (parisByName, defaultValue, names) => { for (const name of names) { if (parisByName[name] && parisByName[name].length) { return parisByName[name][0]; } } return defaultValue; }; const convert = rawData => { requestCount = 1; if (!rawData.match(/^\s*curl /)) { return null; } // Parse the whole thing into one big tokenized list const parseEntries = (0, shell_quote_1.parse)(rawData); // ~~~~~~~~~~~~~~~~~~~~~~ // // Aggregate the commands // // ~~~~~~~~~~~~~~~~~~~~~~ // const commands = []; let currentCommand = []; for (const parseEntry of parseEntries) { if (typeof parseEntry === 'string') { if (parseEntry.startsWith('$')) { currentCommand.push(parseEntry.slice(1, Infinity)); } else { currentCommand.push(parseEntry); } continue; } if (parseEntry.comment) { continue; } const { op } = parseEntry; // `;` separates commands if (op === ';') { commands.push(currentCommand); currentCommand = []; continue; } if (op === null || op === void 0 ? void 0 : op.startsWith('$')) { // Handle the case where literal like -H $'Header: \'Some Quoted Thing\'' const str = op.slice(2, op.length - 1).replace(/\\'/g, "'"); currentCommand.push(str); continue; } if (op === 'glob') { currentCommand.push(parseEntry.pattern); continue; } // Not sure what else this could be, so just keep going } // Push the last unfinished command commands.push(currentCommand); const requests = commands .filter(command => command[0] === 'curl') .map(importCommand); return requests; }; exports.convert = convert; //# sourceMappingURL=curl.js.map