Skip to content

Instantly share code, notes, and snippets.

@wesleyegberto
Created September 22, 2020 05:57
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save wesleyegberto/8994f8d20b33970ad8304f285e91b0e5 to your computer and use it in GitHub Desktop.
Save wesleyegberto/8994f8d20b33970ad8304f285e91b0e5 to your computer and use it in GitHub Desktop.
Script to convert a Postman backupt to Insomnia
/**
* Script to parse a Postman backupt to Insomnia keeping the same structure.
*
* It parses:
* - Folders
* - Requests
* - Environments
*
* Notes: Insomnia doesn't accept vars with dots, if you are using you must replace yours URLs manually (see ENVIRONMENTS_EXPORTS).
*/
'use strict';
const fs = require('fs');
const postmanDump = require('./Backup.postman_dump.json');
if (!postmanDump) {
throw new Error('Invalid JSON');
}
if (postmanDump.version != 1) {
throw new Error('Version not supported, try 1!');
}
function generateId(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
String.prototype.toId = function toId() {
return this.replace(/-/g, '');
};
// always a new workspace to avoid problems
const WORKDIR = 'wrk_' + generateId(20);
const ENVBASE = 'env_' + generateId(20);
const resources = [
{
_id: WORKDIR,
_type: 'workspace',
name: 'Postman Dump ' + (new Date()).toISOString(),
parentId: null,
scope: null,
},
{
_id: 'spc_' + generateId(20),
_type: 'api_spec',
parentId: WORKDIR,
fileName: 'Insomnia',
contents: '',
contentType: 'yaml',
},
{
_id: ENVBASE,
_type: 'environment',
parentId: WORKDIR,
name: 'Base Environment',
data: {},
dataPropertyOrder: {},
color: null,
isPrivate: false,
metaSortKey: 1597080078957,
},
];
function mapRequest(request) {
const parentId = request.folder|| request.collectionId;
const mapped = {
_id: 'req_' + request.id.toId(),
_type: 'request',
parentId: 'fld_' + parentId.toId(),
name: request.name,
description: request.description || '',
url: request.url || '',
method: request.method,
};
if (request.headerData && request.headerData.length) {
mapped.headers = request.headerData.map(header => ({
id: 'pair_' + generateId(10),
name: header.key,
value: header.value,
}));
}
if (request.queryParams && request.queryParams.length) {
mapped.parameters = request.queryParams.map(param => ({
id: 'pair_' + generateId(10),
name: param.key,
value: param.value,
disabled: !param.enabled,
}));
}
if (request.auth) {
mapped.authentication = {
type: request.auth.type
};
if (request.auth.bearer && request.auth.bearer.length > 0) {
mapped.authentication.token = request.auth.bearer[0].value
}
}
if (request.dataMode == 'urlencoded' && request.data && request.data.length) {
mapped.body = {
mimeType: 'application/x-www-form-urlencoded',
params: request.data.map(param => ({
id: 'pair_' + generateId(10),
name: param.key,
value: param.value
}))
};
}
if (request.dataMode == 'raw') {
mapped.body = {
mimeType: 'application/json',
text: request.rawModeData,
};
}
return mapped;
}
function parseFolder(collection, folders) {
const parent = {
_id: 'fld_' + collection.id.toId(),
_type: 'request_group',
name: collection.name,
description: collection.description,
parentId: collection.parentId,
};
resources.push(parent);
if (collection.folders_order && collection.folders_order.length) {
console.log(collection.id, '- Verifying folders');
folders.forEach(folder => {
if (collection.folders_order.findIndex(fId => fId == folder.id) > -1) {
console.log('Parent: ', collection.id, ':', parent._id, ' -> ', folder.id);
folder.parentId = parent._id;
parseFolder(folder, folders);
}
});
}
}
function parseCollection(collection) {
collection.parentId = WORKDIR;
console.log('Collection', collection.name, '- Folders:', collection.folders.length, '- Requests:', collection.requests.length);
parseFolder(collection, collection.folders);
if (collection.requests && collection.requests.length) {
collection.requests.forEach(request => {
resources.push(mapRequest(request));
});
}
}
console.log('Starting parsing');
if (postmanDump && postmanDump.collections) {
console.log('Parsing collections');
postmanDump.collections.forEach(collection => parseCollection(collection));
}
// ENVIRONMENTS_EXPORTS
if (postmanDump.environments && postmanDump.environments.length) {
console.log('Parsing environments');
postmanDump.environments.forEach(env => {
console.log('Adding environment:', env.name);
const mapped = {
_id: 'env_' + env.id.toId(),
_type: 'environment',
parentId: ENVBASE,
name: env.name,
data: {}
};
if (env.values && env.values.length) {
env.values.forEach(item => {
const key = item.key.replace(/[-.]/g, '_');
mapped.data[key] = item.value;
});
}
resources.push(mapped);
});
}
console.log('Finished parsing, exporting JSON');
const data = JSON.stringify({
_type: 'export',
__export_format: 4,
resources: resources,
});
fs.writeFileSync('insomnia-converted-from-postman.json', data);
console.log('Exported finished');
@miadabdi
Copy link

Postman won't dump a Backup.postman_dump.json file.
It dumps a zip file containing all collections.

@bouldersoftware
Copy link

Worked perfectly. Thanks! From Postman v9. Created the Backup.postman_dump.json. Imported perfectly.

@f5scott
Copy link

f5scott commented Jun 23, 2023

Backup file is now a ZIP from postman, the ZIP contains a collection
Error: Cannot find module './Backup.postman_dump.json'

image
image

@aknosis
Copy link

aknosis commented Aug 4, 2023

With a Postman export like the above pictured, you can import each .json file in a collection with Insomnia under Preferences -> Data.

I did not see a method of importing environments.

@beedle-
Copy link

beedle- commented Aug 7, 2023

Since the feature to dump all data is gone (postmanlabs/postman-app-support#11738), I used the last backup file from C:\Users<username>\AppData\Roaming\Postman and it worked like a charm. (Windows 11).
Thank you for the Script.

@beedle-
Copy link

beedle- commented Aug 7, 2023

Default headers were not exported (i.e. Content-Type)

@erdincay
Copy link

thx, i will try this script, can it export tests too?

@KooperL
Copy link

KooperL commented Sep 19, 2023

Star, worked perfectly!

@dkimbell13
Copy link

Worked great for me

@anschoewe
Copy link

Now that Postman removed their Scratchpad features, this is essential. Worked liked a charm. Thank you!

@adilfulara
Copy link

Do you plan to support v2 of postman format?

node converter.js
/Users/afulara/Development/tools/postman-to-insomnia/converter.js:22
  throw new Error('Version not supported, try 1!');
  ^

Error: Version not supported, try 1!
    at Object.<anonymous> (/Users/afulara/Development/tools/postman-to-insomnia/converter.js:22:9)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:23:47

Node.js v18.12.1

@vigsank
Copy link

vigsank commented Sep 26, 2023

Awesome!! Worked nicely. Thanks a ton. Starred.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment