diff --git a/packages/bruno-app/src/utils/importers/postman-collection.js b/packages/bruno-app/src/utils/importers/postman-collection.js index f4c369570..cc05d1994 100644 --- a/packages/bruno-app/src/utils/importers/postman-collection.js +++ b/packages/bruno-app/src/utils/importers/postman-collection.js @@ -23,7 +23,8 @@ const postmanToBruno = (collection) => { }; const isPostmanCollection = (data) => { - const info = data.info; + // Newer Postman exports wrap the collection in a { collection: { ... } } envelope + const info = data.info || data?.collection?.info; if (!info || typeof info !== 'object') { return false; } diff --git a/packages/bruno-converters/src/postman/postman-to-bruno.js b/packages/bruno-converters/src/postman/postman-to-bruno.js index 277ec4bf5..9316ea6cc 100644 --- a/packages/bruno-converters/src/postman/postman-to-bruno.js +++ b/packages/bruno-converters/src/postman/postman-to-bruno.js @@ -950,7 +950,10 @@ const importPostmanV2Collection = async (collection, { useWorkers = false }) => const parsePostmanCollection = async (collection, { useWorkers = false }) => { try { - let schema = get(collection, 'info.schema'); + // Newer Postman exports wrap the collection in a { collection: { ... } } envelope + const parsedCollection = collection.collection?.info ? collection.collection : collection; + + let schema = get(parsedCollection, 'info.schema'); let v2Schemas = [ 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json', @@ -960,7 +963,7 @@ const parsePostmanCollection = async (collection, { useWorkers = false }) => { ]; if (v2Schemas.includes(schema)) { - return await importPostmanV2Collection(collection, { useWorkers }); + return await importPostmanV2Collection(parsedCollection, { useWorkers }); } throw new Error('Unsupported Postman schema version. Only Postman Collection v2.0 and v2.1 are supported.'); diff --git a/packages/bruno-converters/tests/postman/postman-to-bruno/postman-to-bruno.spec.js b/packages/bruno-converters/tests/postman/postman-to-bruno/postman-to-bruno.spec.js index 374432da9..1e02b4277 100644 --- a/packages/bruno-converters/tests/postman/postman-to-bruno/postman-to-bruno.spec.js +++ b/packages/bruno-converters/tests/postman/postman-to-bruno/postman-to-bruno.spec.js @@ -1120,6 +1120,15 @@ describe('postman-collection', () => { expect(headers[1].value).toBe('example.com'); }); + it('should unwrap and import a Postman collection with { collection: { ... } } envelope', async () => { + const wrappedCollection = { + collection: { ...postmanCollection } + }; + + const brunoCollection = await postmanToBruno(wrappedCollection); + expect(brunoCollection).toMatchObject(expectedOutput); + }); + it('should handle string headers with no value', async () => { const collectionWithNoValueHeader = { info: { diff --git a/tests/import/postman/fixtures/postman-v21-wrapped.json b/tests/import/postman/fixtures/postman-v21-wrapped.json new file mode 100644 index 000000000..44b123951 --- /dev/null +++ b/tests/import/postman/fixtures/postman-v21-wrapped.json @@ -0,0 +1,66 @@ +{ + "collection": { + "info": { + "name": "Postman v2.1 Wrapped Collection", + "description": "Test collection using newer Postman export format with collection envelope", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_postman_id": "beaf4d12-a72a-47cb-902d-2942a68a59c4" + }, + "item": [ + { + "name": "Get Users", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}", + "type": "text" + } + ], + "url": { + "raw": "{{baseUrl}}/users", + "host": ["{{baseUrl}}"], + "path": ["users"], + "query": [ + { + "key": "page", + "value": "1" + } + ] + } + }, + "response": [] + }, + { + "name": "Create User", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"John Doe\",\n \"email\": \"john@example.com\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": ["{{baseUrl}}"], + "path": ["users"] + } + }, + "response": [] + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "https://api.example.com" + } + ] + } +} diff --git a/tests/import/postman/import-postman-v21-wrapped.spec.ts b/tests/import/postman/import-postman-v21-wrapped.spec.ts new file mode 100644 index 000000000..6d845d8b3 --- /dev/null +++ b/tests/import/postman/import-postman-v21-wrapped.spec.ts @@ -0,0 +1,17 @@ +import { test } from '../../../playwright'; +import * as path from 'path'; +import { closeAllCollections, importCollection } from '../../utils/page'; + +test.describe('Import Postman Collection v2.1 (wrapped format)', () => { + test.afterEach(async ({ page }) => { + await closeAllCollections(page); + }); + + test('Import Postman Collection v2.1 with collection envelope successfully', async ({ page, createTmpDir }) => { + const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-v21-wrapped.json'); + + await importCollection(page, postmanFile, await createTmpDir('postman-v21-wrapped-test'), { + expectedCollectionName: 'Postman v2.1 Wrapped Collection' + }); + }); +});