UNPKG

insomnia-plugin-postman-export

Version:

This is a plugin for [insomnia](https://insomnia.rest) for exporting its request data in Postman format.

268 lines (241 loc) 10 kB
const fs = require("fs"); const {v4: uuidv4} = require('uuid') const inputFileName = 'requests.json';//process.argv.length > 2 ? process.argv[2] : undefined; /*if(inputFileName === undefined) { console.error("Error: Input file not provided!!! Exiting."); process.exit(1); }*/ function transformEnvironments(insomniaResources) { const environments = insomniaResources.filter(resource => resource._type === 'environment'); if (environments.length === 0) return []; const environment = environments[0]; const variables = environment.kvPairData.map(pair => ({ key: pair.name, value: pair.value })); return variables; } function transformUrl(insomniaUrl, insomniaUrlParams) { if (insomniaUrl === '') return {}; var postmanUrl = {}; postmanUrl.raw = insomniaUrl; if (insomniaUrlParams && insomniaUrlParams.length > 0) { postmanUrl.query = []; if(postmanUrl.raw !== undefined && postmanUrl.raw.includes("?")) { const rawUrlSplit = postmanUrl.raw.split("?"); postmanUrl.raw = rawUrlSplit[0]; const rawUrlParams = rawUrlSplit[1].split("&"); rawUrlParams.forEach(kvPair => { const kvPairSplit = kvPair.split("="); postmanUrl.query.push({key: kvPairSplit[0], value: kvPairSplit[1]}); }); } // maybe this mixing should not be allowed in insomnia itself (but as long as it's there the above will take care of honoring it); I think I once saw duplication of a kv pair with the older value retained in the duplicate kv pair insomniaUrlParams.forEach(param => { postmanUrl.query.push({key: param.name, value: param.value}); }); } var urlParts = postmanUrl.raw.split(/\:\/\//); var rawHostAndPath; if (urlParts.length === 1) { rawHostAndPath=urlParts[0]; } else if (urlParts.length === 2){ postmanUrl.protocol = urlParts[0]; rawHostAndPath=urlParts[1]; } else { console.error("Error: Unexpected number of components found in the URL string. Exiting."); process.exit(3); } // https://stackoverflow.com/questions/4607745/split-string-only-on-first-instance-of-specified-character const hostAndPath = rawHostAndPath.split(/\/(.+)/); postmanUrl.host = hostAndPath[0].split(/\./); postmanUrl.path = hostAndPath[1] === undefined ? [] : hostAndPath[1].split(/\//); return postmanUrl; } function transformHeaders(insomniaHeaders) { var outputHeaders = []; insomniaHeaders.forEach(element => { var header = {}; header.key = element.name; header.value = element.value; outputHeaders.push(header) }); return outputHeaders; } function transformBody(insomniaBody) { var body = {}; switch (insomniaBody.mimeType) { case "": case "application/json": case "application/xml": body.mode = "raw"; body.raw = insomniaBody.text; break; case "multipart/form-data": body.mode = "formdata"; body.formdata = []; insomniaBody.params.forEach(param => { body.formdata.push({key: param.name, value: param.value}); }); break; case "application/x-www-form-urlencoded": body.mode = "urlencoded"; body.urlencoded = []; insomniaBody.params.forEach(param => { body.urlencoded.push({key: param.name, value: param.value}); }); break; case "application/octet-stream": body.mode = "file"; body.file = {}; body.file.src = "/C:/PleaseSelectAFile"; console.warn("Warning: A file is supposed to be a part of the request!!! Would need to be manually selected in Postman."); break; case "application/graphql": var graphqlBody = JSON.parse(insomniaBody.text); body.mode = "graphql"; body.graphql = {}; body.graphql.query = graphqlBody.query; body.graphql.variables = JSON.stringify(graphqlBody.variables) break; default: console.warn("Warning: Body type unsupported; skipped!!! ... " + insomniaBody.mimeType); body.mode = "raw"; body.raw = "github.com/Vyoam/InsomniaToPostmanFormat: Unsupported body type "+insomniaBody.mimeType; break; } return body; } function transformItem(insomniaItem) { var postmanItem = {}; postmanItem.name = insomniaItem.name; var request = {}; request.description = insomniaItem.description; request.method = insomniaItem.method; request.header = transformHeaders(insomniaItem.headers); if ( Object.keys(insomniaItem.body).length !== 0 ) { request.body = transformBody(insomniaItem.body); } request.url = transformUrl(insomniaItem.url, insomniaItem.parameters); request.auth = {}; // todo if ( Object.keys(insomniaItem.authentication).length !== 0 ) { console.warn("Warning: Auth param export not yet supported!!!"); } postmanItem.request = request; postmanItem.response = []; if (insomniaItem.afterResponseScript && insomniaItem.afterResponseScript.trim() !== "") { postmanItem.event = [{ listen: "test", script: { type: "text/javascript", exec: insomniaItem.afterResponseScript.split('\n').map(line => line.trim().replace("insomnia", "pm")) } }]; } return postmanItem; } const rootId = "d1097c3b-2011-47a4-8f95-87b8f4b54d6d"; // unique guid for root function generateMaps(insomniaParentChildList) { var parentChildrenMap = new Map(); var flatMap = new Map(); insomniaParentChildList.forEach(element => { flatMap.set(element._id, element); switch (element._type) { case "workspace": // 'bug': only one workspace to be selected (the last one which comes up here) var elementArray = []; elementArray.push(element); parentChildrenMap.set(rootId, elementArray); // in any case will select the top workspace when creating tree break; case "request": var elementArray = parentChildrenMap.get(element.parentId); if (elementArray === undefined) elementArray = []; elementArray.push(element); parentChildrenMap.set(element.parentId, elementArray); break; case "request_group": var elementArray = parentChildrenMap.get(element.parentId); if (elementArray === undefined) elementArray = []; elementArray.push(element); parentChildrenMap.set(element.parentId, elementArray); break; default: console.warn("Warning: Item type unsupported; skipped!!! ... " + element._type); } }); const maps = [parentChildrenMap, flatMap]; return maps; } function generateTreeRecursively(element, parentChildrenMap, filters) { var postmanItem = {}; switch (element._type) { case "request_group": postmanItem.name = element.name; postmanItem.item = []; parentChildrenMap.get(element._id).forEach(child => { const generatedItem = generateTreeRecursively(child, parentChildrenMap, filters); if(generatedItem!==null) { //// postmanItem.item.push(generatedItem); } }); if(postmanItem.item.length===0) { //// postmanItem = null; } break; case "request": postmanItem = null; if(filters.nameRegex.test(element.name) || filters.workspaceIds.includes(element._id)) { //// postmanItem = transformItem(element); } break; default: console.warn("Warning: Item type unsupported; skipped!!! ... " + element._type); } return postmanItem; } function getSubItemTrees(parentChildrenMap, filters) { var subItemTrees = []; var roots = parentChildrenMap.get(rootId); parentChildrenMap.get(roots[0]._id).forEach(element => { const generatedItem = generateTreeRecursively(element, parentChildrenMap, filters); if(generatedItem!==null) { //// subItemTrees.push(generatedItem); } }); if(subItemTrees.length===0) { //// subItemTrees = null; } return subItemTrees; } module.exports.transformData = (inputDataString, filters) => { var inputData = JSON.parse(inputDataString); if(inputData.__export_format!==4) { console.error("Error: Version (__export_format "+inputData.__export_format+") not supported. Only version 4 is supported."); process.exit(2); } var outputData = { "info": { "_postman_id": "", "name": "", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [], "variable": [] }; outputData.info._postman_id = uuidv4(); var maps = generateMaps(inputData.resources); var parentChildrenMap = maps[0]; var flatMap = maps[1]; const subItems = getSubItemTrees(parentChildrenMap, filters); if(subItems!==null){ //// outputData.item.push(...subItems); } outputData.info.name = inputFileName.slice(0, -5); // assuming extension is .json const environmentVariables = transformEnvironments(inputData.resources); if (environmentVariables.length > 0) { outputData.variable.push(...environmentVariables); } return JSON.stringify(outputData); } //const data = fs.readFileSync(inputFileName, "utf-8"); //const newData = transformData(data); //fs.writeFileSync(inputFileName.slice(0, -5) + ".postman_collection.json", newData);