mirror of
https://github.com/usebruno/bruno.git
synced 2025-05-05 15:32:58 +00:00
feat: add insomnia v5 import (#4468)
This commit is contained in:
parent
54a03fd0d3
commit
e5ebe20a20
@ -159,7 +159,79 @@ const transformInsomniaRequestItem = (request, index, allRequests) => {
|
||||
return brunoRequestItem;
|
||||
};
|
||||
|
||||
const parseInsomniaCollection = (_insomniaCollection) => {
|
||||
const isInsomniaV5Export = (data) => {
|
||||
// V5 format has a type property at the root level
|
||||
if (data.type && data.type.startsWith('collection.insomnia.rest/5')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const parseInsomniaV5Collection = (data) => {
|
||||
const brunoCollection = {
|
||||
name: data.name || 'Untitled Collection',
|
||||
uid: uuid(),
|
||||
version: '1',
|
||||
items: [],
|
||||
environments: []
|
||||
};
|
||||
|
||||
try {
|
||||
// Parse the collection items
|
||||
const parseCollectionItems = (items, allItems = []) => {
|
||||
if (!Array.isArray(items)) {
|
||||
throw new Error('Invalid items format: expected array');
|
||||
}
|
||||
|
||||
return items.map((item, index) => {
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// In v5, requests might be defined with method property or meta.type
|
||||
if (item.method && item.url) {
|
||||
const request = {
|
||||
_id: item.meta?.id || uuid(),
|
||||
name: item.name || 'Untitled Request',
|
||||
url: item.url || '',
|
||||
method: item.method || '',
|
||||
headers: item.headers || [],
|
||||
parameters: item.parameters || [],
|
||||
pathParameters: item.pathParameters || [],
|
||||
authentication: item.authentication || {},
|
||||
body: item.body || {}
|
||||
};
|
||||
return transformInsomniaRequestItem(request, index, allItems);
|
||||
} else if (item.children && Array.isArray(item.children)) {
|
||||
// Process folder
|
||||
return {
|
||||
uid: uuid(),
|
||||
name: item.name || 'Untitled Folder',
|
||||
type: 'folder',
|
||||
items: parseCollectionItems(item.children, item.children)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}).filter(Boolean);
|
||||
};
|
||||
|
||||
if (data.collection && Array.isArray(data.collection)) {
|
||||
brunoCollection.items = parseCollectionItems(data.collection, data.collection);
|
||||
}
|
||||
|
||||
// Parse environments if available
|
||||
if (data.environments) {
|
||||
// Handle environments implementation if needed
|
||||
}
|
||||
|
||||
return brunoCollection;
|
||||
} catch (err) {
|
||||
console.error('Error parsing collection:', err);
|
||||
throw new Error('An error occurred while parsing the Insomnia v5 collection: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const parseInsomniaCollection = (data) => {
|
||||
const brunoCollection = {
|
||||
name: '',
|
||||
uid: uuid(),
|
||||
@ -169,8 +241,7 @@ const parseInsomniaCollection = (_insomniaCollection) => {
|
||||
};
|
||||
|
||||
try {
|
||||
const insomniaExport = _insomniaCollection;
|
||||
const insomniaResources = get(insomniaExport, 'resources', []);
|
||||
const insomniaResources = get(data, 'resources', []);
|
||||
const insomniaCollection = insomniaResources.find((resource) => resource._type === 'workspace');
|
||||
|
||||
if (!insomniaCollection) {
|
||||
@ -180,8 +251,8 @@ const parseInsomniaCollection = (_insomniaCollection) => {
|
||||
brunoCollection.name = insomniaCollection.name;
|
||||
|
||||
const requestsAndFolders =
|
||||
insomniaResources.filter((resource) => resource._type === 'request' || resource._type === 'request_group') ||
|
||||
[];
|
||||
insomniaResources.filter((resource) => resource._type === 'request' || resource._type === 'request_group') ||
|
||||
[];
|
||||
|
||||
function createFolderStructure(resources, parentId = null) {
|
||||
const requestGroups =
|
||||
@ -194,11 +265,13 @@ const parseInsomniaCollection = (_insomniaCollection) => {
|
||||
(resource) => resource._type === 'request' && resource.parentId === folder._id
|
||||
);
|
||||
|
||||
return {
|
||||
return {
|
||||
uid: uuid(),
|
||||
name,
|
||||
type: 'folder',
|
||||
items: createFolderStructure(resources, folder._id).concat(requests.map(transformInsomniaRequestItem))
|
||||
items: createFolderStructure(resources, folder._id).concat(
|
||||
requests.filter(r => r.parentId === folder._id).map(transformInsomniaRequestItem)
|
||||
)
|
||||
};
|
||||
});
|
||||
|
||||
@ -208,20 +281,27 @@ const parseInsomniaCollection = (_insomniaCollection) => {
|
||||
brunoCollection.items = createFolderStructure(requestsAndFolders, insomniaCollection._id);
|
||||
return brunoCollection;
|
||||
} catch (err) {
|
||||
throw new Error('An error occurred while parsing the Insomnia collection');
|
||||
console.error('Error parsing collection:', err);
|
||||
throw new Error('An error occurred while parsing the Insomnia collection: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
export const insomniaToBruno = (insomniaCollection) => {
|
||||
try {
|
||||
const collection = parseInsomniaCollection(insomniaCollection);
|
||||
let collection;
|
||||
if (isInsomniaV5Export(insomniaCollection)) {
|
||||
collection = parseInsomniaV5Collection(insomniaCollection);
|
||||
} else {
|
||||
collection = parseInsomniaCollection(insomniaCollection);
|
||||
}
|
||||
|
||||
const transformedCollection = transformItemsInCollection(collection);
|
||||
const hydratedCollection = hydrateSeqInCollection(transformedCollection);
|
||||
const validatedCollection = validateSchema(hydratedCollection);
|
||||
return validatedCollection;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw new Error('Import collection failed');
|
||||
throw new Error('Import collection failed: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,160 @@
|
||||
import { describe, it, expect } from '@jest/globals';
|
||||
import insomniaToBruno from '../../src/insomnia/insomnia-to-bruno';
|
||||
import jsyaml from 'js-yaml';
|
||||
|
||||
describe('insomnia-collection', () => {
|
||||
it('should correctly import a valid Insomnia v5 collection file', async () => {
|
||||
const brunoCollection = insomniaToBruno(jsyaml.load(insomniaCollection));
|
||||
|
||||
expect(brunoCollection).toMatchObject(expectedOutput)
|
||||
});
|
||||
});
|
||||
|
||||
const insomniaCollection = `
|
||||
type: collection.insomnia.rest/5.0
|
||||
name: Hello World Workspace Insomnia
|
||||
meta:
|
||||
id: wrk_9381cf78cb0a4eaaab1d571f29f928dc
|
||||
created: 1744194421962
|
||||
modified: 1744194421962
|
||||
collection:
|
||||
- name: Folder1
|
||||
meta:
|
||||
id: fld_6beacec0bd2f4370be98169217e82a2c
|
||||
created: 1744194421968
|
||||
modified: 1744194421968
|
||||
sortKey: -1744194421968
|
||||
children:
|
||||
- url: https://httpbin.org/get
|
||||
name: Request1
|
||||
meta:
|
||||
id: req_e9fbdc9c88984068a04f442e052d4ff1
|
||||
created: 1744194421965
|
||||
modified: 1744194421965
|
||||
isPrivate: false
|
||||
sortKey: -1744194421965
|
||||
method: GET
|
||||
settings:
|
||||
renderRequestBody: true
|
||||
encodeUrl: true
|
||||
followRedirects: global
|
||||
cookies:
|
||||
send: true
|
||||
store: true
|
||||
rebuildPath: true
|
||||
- name: Folder2
|
||||
meta:
|
||||
id: fld_96508d79bf06420a853b07482ab280d7
|
||||
created: 1744194421969
|
||||
modified: 1744194421969
|
||||
sortKey: -1744194421969
|
||||
children:
|
||||
- url: https://httpbin.org/get
|
||||
name: Request2
|
||||
meta:
|
||||
id: req_3c572aa26a964f1f800bfa5c53cacb75
|
||||
created: 1744194421967
|
||||
modified: 1744194421967
|
||||
isPrivate: false
|
||||
sortKey: -1744194421968
|
||||
method: GET
|
||||
settings:
|
||||
renderRequestBody: true
|
||||
encodeUrl: true
|
||||
followRedirects: global
|
||||
cookies:
|
||||
send: true
|
||||
store: true
|
||||
rebuildPath: true
|
||||
cookieJar:
|
||||
name: Default Jar
|
||||
meta:
|
||||
id: jar_9ecb97079037c7d5bb888f0bfdec9b0e1275c6d1
|
||||
created: 1744194421971
|
||||
modified: 1744194421971
|
||||
environments:
|
||||
name: Imported Environment
|
||||
meta:
|
||||
id: env_a8a9a8ff952d4d079edf53f8ee22a423
|
||||
created: 1744194421970
|
||||
modified: 1744194421970
|
||||
isPrivate: false
|
||||
data:
|
||||
var1: value1
|
||||
var2: value2
|
||||
`
|
||||
|
||||
const expectedOutput = {
|
||||
"environments": [],
|
||||
"items": [
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"name": "Request1",
|
||||
"request": {
|
||||
"auth": {
|
||||
"basic": null,
|
||||
"bearer": null,
|
||||
"digest": null,
|
||||
"mode": "none",
|
||||
},
|
||||
"body": {
|
||||
"formUrlEncoded": [],
|
||||
"json": null,
|
||||
"mode": "none",
|
||||
"multipartForm": [],
|
||||
"text": null,
|
||||
"xml": null,
|
||||
},
|
||||
"headers": [],
|
||||
"method": "GET",
|
||||
"params": [],
|
||||
"url": "https://httpbin.org/get",
|
||||
},
|
||||
"seq": 1,
|
||||
"type": "http-request",
|
||||
"uid": "mockeduuidvalue123456",
|
||||
},
|
||||
],
|
||||
"name": "Folder1",
|
||||
"type": "folder",
|
||||
"uid": "mockeduuidvalue123456",
|
||||
},
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"name": "Request2",
|
||||
"request": {
|
||||
"auth": {
|
||||
"basic": null,
|
||||
"bearer": null,
|
||||
"digest": null,
|
||||
"mode": "none",
|
||||
},
|
||||
"body": {
|
||||
"formUrlEncoded": [],
|
||||
"json": null,
|
||||
"mode": "none",
|
||||
"multipartForm": [],
|
||||
"text": null,
|
||||
"xml": null,
|
||||
},
|
||||
"headers": [],
|
||||
"method": "GET",
|
||||
"params": [],
|
||||
"url": "https://httpbin.org/get",
|
||||
},
|
||||
"seq": 1,
|
||||
"type": "http-request",
|
||||
"uid": "mockeduuidvalue123456",
|
||||
},
|
||||
],
|
||||
"name": "Folder2",
|
||||
"type": "folder",
|
||||
"uid": "mockeduuidvalue123456",
|
||||
},
|
||||
],
|
||||
"name": "Hello World Workspace Insomnia",
|
||||
"uid": "mockeduuidvalue123456",
|
||||
"version": "1",
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user