From b90257d8e950a1ce10648e6f6f99c7ee1b615110 Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 6 May 2026 00:29:30 +0530 Subject: [PATCH 1/6] refactor: remove 'idx' method from headerList and update related tests - Eliminated the 'idx' method from both req.headerList and res.headerList to streamline header management. - Updated associated tests and documentation to reflect the removal, ensuring clarity in the API usage and maintaining consistency across the header management system. --- .../src/utils/codemirror/autocomplete.js | 2 -- .../src/sandbox/quickjs/shims/bruno-request.js | 2 +- .../src/sandbox/quickjs/shims/bruno-response.js | 2 +- packages/bruno-js/tests/header-list.spec.js | 16 ---------------- .../api/req/headerList/read-methods.bru | 7 ------- .../api/res/headerList/read-methods.bru | 7 ------- 6 files changed, 2 insertions(+), 34 deletions(-) diff --git a/packages/bruno-app/src/utils/codemirror/autocomplete.js b/packages/bruno-app/src/utils/codemirror/autocomplete.js index ed61a0880c8..1f672ae8d83 100644 --- a/packages/bruno-app/src/utils/codemirror/autocomplete.js +++ b/packages/bruno-app/src/utils/codemirror/autocomplete.js @@ -43,7 +43,6 @@ const STATIC_API_HINTS = { 'req.headerList.get(name)', 'req.headerList.one(name)', 'req.headerList.all()', - 'req.headerList.idx(index)', 'req.headerList.count()', 'req.headerList.has(name)', 'req.headerList.has(name, value)', @@ -88,7 +87,6 @@ const STATIC_API_HINTS = { 'res.headerList.get(name)', 'res.headerList.one(name)', 'res.headerList.all()', - 'res.headerList.idx(index)', 'res.headerList.count()', 'res.headerList.has(name)', 'res.headerList.has(name, value)', diff --git a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js index e4ce5ac6ff6..0188e0d2005 100644 --- a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js +++ b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js @@ -38,7 +38,7 @@ const addBrunoRequestShimToContext = (vm, req) => { const { evalCode: headersEvalCode } = createPropertyListBridge(vm, req.headerList, headerListObj, { globalPath: 'globalThis.req.headerList', syncReadMethods: ['get', 'has', 'count', 'indexOf', 'toObject', 'toString'], - syncReadObjectMethods: ['one', 'all', 'idx', 'toJSON'], + syncReadObjectMethods: ['one', 'all', 'toJSON'], syncWriteMethods: ['append', 'set', 'delete', 'clear', 'populate', 'repopulate', 'assimilate'], withIterators: true }); diff --git a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js index 329e198dab2..142d1903bd1 100644 --- a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js +++ b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js @@ -63,7 +63,7 @@ const addBrunoResponseShimToContext = (vm, res) => { const bridge = createPropertyListBridge(vm, res.headerList, headerListObj, { globalPath: 'globalThis.res.headerList', syncReadMethods: ['get', 'has', 'count', 'indexOf', 'toObject', 'toString'], - syncReadObjectMethods: ['one', 'all', 'idx', 'toJSON'], + syncReadObjectMethods: ['one', 'all', 'toJSON'], syncWriteMethods: ['append', 'set', 'delete', 'clear', 'populate', 'repopulate', 'assimilate'], withIterators: true }); diff --git a/packages/bruno-js/tests/header-list.spec.js b/packages/bruno-js/tests/header-list.spec.js index bf1f10d56b4..61f4780c4e4 100644 --- a/packages/bruno-js/tests/header-list.spec.js +++ b/packages/bruno-js/tests/header-list.spec.js @@ -73,17 +73,6 @@ describe('HeaderList (req.headerList)', () => { expect(a1).not.toBe(a2); }); - test('idx() returns header at position', () => { - const { list } = createReqHeaders(); - expect(list.idx(0)).toEqual({ key: 'Content-Type', value: 'application/json' }); - expect(list.idx(2)).toEqual({ key: 'Accept', value: '*/*' }); - }); - - test('idx() returns undefined for out-of-bounds', () => { - const { list } = createReqHeaders(); - expect(list.idx(10)).toBeUndefined(); - }); - test('count() returns number of headers', () => { const { list } = createReqHeaders(); expect(list.count()).toBe(3); @@ -923,11 +912,6 @@ describe('Response Headers (res.headerList)', () => { expect(headerList.count()).toBe(3); }); - test('idx() returns header at position', () => { - const { headerList } = createResHeaders(); - expect(headerList.idx(1)).toEqual({ key: 'x-request-id', value: 'abc-123' }); - }); - test('indexOf() finds structurally-equal header', () => { const { headerList } = createResHeaders(); expect(headerList.indexOf({ key: 'content-type', value: 'application/json' })).toBe(0); diff --git a/packages/bruno-tests/collection/scripting/api/req/headerList/read-methods.bru b/packages/bruno-tests/collection/scripting/api/req/headerList/read-methods.bru index 764568b2f4d..9c54cae20b7 100644 --- a/packages/bruno-tests/collection/scripting/api/req/headerList/read-methods.bru +++ b/packages/bruno-tests/collection/scripting/api/req/headerList/read-methods.bru @@ -44,13 +44,6 @@ tests { expect(keys).to.include('x-custom'); }); - test("req.headerList.idx(index)", function() { - const first = req.headerList.idx(0); - expect(first).to.have.property('key'); - expect(first).to.have.property('value'); - expect(req.headerList.idx(-1)).to.be.undefined; - }); - test("req.headerList.count()", function() { expect(req.headerList.count()).to.be.at.least(3); }); diff --git a/packages/bruno-tests/collection/scripting/api/res/headerList/read-methods.bru b/packages/bruno-tests/collection/scripting/api/res/headerList/read-methods.bru index 3553e3645e3..ffb840dee41 100644 --- a/packages/bruno-tests/collection/scripting/api/res/headerList/read-methods.bru +++ b/packages/bruno-tests/collection/scripting/api/res/headerList/read-methods.bru @@ -40,13 +40,6 @@ tests { expect(keys).to.include('x-powered-by'); }); - test("res.headerList.idx(index)", function() { - const first = res.headerList.idx(0); - expect(first).to.have.property('key'); - expect(first).to.have.property('value'); - expect(res.headerList.idx(-1)).to.be.undefined; - }); - test("res.headerList.count()", function() { expect(res.headerList.count()).to.be.at.least(1); }); From 9cdbb0e283fdc7fd11db8746861271d3623b5253 Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 6 May 2026 00:38:34 +0530 Subject: [PATCH 2/6] refactor: block unimplemented HeaderList methods with error messages - Added error handling for unimplemented methods in HeaderList, including idx, add, upsert, remove, each, prepend, insert, and insertAfter. - Each method now throws a descriptive error indicating the appropriate alternative methods to use, enhancing clarity in the API and guiding users towards correct usage. --- packages/bruno-js/src/header-list.js | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/packages/bruno-js/src/header-list.js b/packages/bruno-js/src/header-list.js index 8f5cade6a00..dc588b885ed 100644 --- a/packages/bruno-js/src/header-list.js +++ b/packages/bruno-js/src/header-list.js @@ -151,6 +151,51 @@ class HeaderList extends PropertyList { return { key: str.substring(0, idx).trim(), value: str.substring(idx + 1).trim() }; } + // ── Blocked inherited methods ───────────────────────────────────────── + // These are inherited from PropertyList/ReadOnlyPropertyList but are not + // part of the HeaderList API. They either use old naming or operate on + // the internal _items array instead of the request config. + + /** @throws {Error} Use get(name) or all() instead. */ + idx() { + throw new Error('idx() is not supported on HeaderList. Use get(name) or all() instead.'); + } + + /** @throws {Error} Use append() instead. */ + add() { + throw new Error('add() is not supported on HeaderList. Use append() instead.'); + } + + /** @throws {Error} Use set() instead. */ + upsert() { + throw new Error('upsert() is not supported on HeaderList. Use set() instead.'); + } + + /** @throws {Error} Use delete() instead. */ + remove() { + throw new Error('remove() is not supported on HeaderList. Use delete() instead.'); + } + + /** @throws {Error} Use forEach() instead. */ + each() { + throw new Error('each() is not supported on HeaderList. Use forEach() instead.'); + } + + /** @throws {Error} Not supported — headers are stored as a plain object. */ + prepend() { + throw new Error('prepend() is not supported on HeaderList. Use append() or set() instead.'); + } + + /** @throws {Error} Not supported — headers are stored as a plain object. */ + insert() { + throw new Error('insert() is not supported on HeaderList. Use append() or set() instead.'); + } + + /** @throws {Error} Not supported — headers are stored as a plain object. */ + insertAfter() { + throw new Error('insertAfter() is not supported on HeaderList. Use append() or set() instead.'); + } + // ── Read method overrides (case-insensitive) ────────────────────────── /** From cc31d09905ae201e5f8fa668f27654dda8ff408f Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 6 May 2026 00:54:32 +0530 Subject: [PATCH 3/6] refactor: update error message in idx() method of HeaderList for clarity - Modified the error message in the idx() method to guide users towards using all()[index] or get(name) instead of the unsupported idx() method, enhancing the clarity of the API documentation. --- packages/bruno-js/src/header-list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bruno-js/src/header-list.js b/packages/bruno-js/src/header-list.js index dc588b885ed..c5312a6e0ed 100644 --- a/packages/bruno-js/src/header-list.js +++ b/packages/bruno-js/src/header-list.js @@ -158,7 +158,7 @@ class HeaderList extends PropertyList { /** @throws {Error} Use get(name) or all() instead. */ idx() { - throw new Error('idx() is not supported on HeaderList. Use get(name) or all() instead.'); + throw new Error('idx() is not supported on HeaderList. Use get(name) instead.'); } /** @throws {Error} Use append() instead. */ From c115c19af2410c9fd8ede877e8b69eb3373daf86 Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 6 May 2026 14:30:53 +0530 Subject: [PATCH 4/6] refactor: update HeaderList to extend ReadOnlyPropertyList and remove unimplemented methods - Changed HeaderList to extend ReadOnlyPropertyList instead of PropertyList, streamlining its functionality. - Removed unimplemented methods (prepend, insert, insertAfter) from HeaderList, clarifying the API and guiding users towards using supported methods. - Updated related tests to reflect these changes, ensuring consistency and accuracy in header management. --- .../src/utils/postman-to-bruno-translator.js | 4 ++ packages/bruno-js/src/header-list.js | 50 ++----------------- .../sandbox/quickjs/shims/bruno-request.js | 2 +- .../sandbox/quickjs/shims/bruno-response.js | 2 +- packages/bruno-js/tests/header-list.spec.js | 4 +- 5 files changed, 12 insertions(+), 50 deletions(-) diff --git a/packages/bruno-converters/src/utils/postman-to-bruno-translator.js b/packages/bruno-converters/src/utils/postman-to-bruno-translator.js index fa9ae4dc680..70b4863dc41 100644 --- a/packages/bruno-converters/src/utils/postman-to-bruno-translator.js +++ b/packages/bruno-converters/src/utils/postman-to-bruno-translator.js @@ -66,6 +66,10 @@ const simpleTranslations = { 'pm.request.headers.reduce': 'req.headerList.reduce', 'pm.request.headers.toObject': 'req.headerList.toObject', 'pm.request.headers.clear': 'req.headerList.clear', + // Lossy: positional inserts map to append (position irrelevant for headers) + 'pm.request.headers.prepend': 'req.headerList.append', + 'pm.request.headers.insert': 'req.headerList.append', + 'pm.request.headers.insertAfter': 'req.headerList.append', // Response headers PropertyList methods (read-only) 'pm.response.headers.has': 'res.headerList.has', diff --git a/packages/bruno-js/src/header-list.js b/packages/bruno-js/src/header-list.js index c5312a6e0ed..dd593b5766d 100644 --- a/packages/bruno-js/src/header-list.js +++ b/packages/bruno-js/src/header-list.js @@ -1,4 +1,3 @@ -const PropertyList = require('./property-list'); const ReadOnlyPropertyList = require('./readonly-property-list'); /** @@ -78,7 +77,7 @@ const ReadOnlyPropertyList = require('./readonly-property-list'); * | `repopulate(items)` | Clears all, then populates with new items | * | `assimilate(source, prune?)` | Merges headers; prune removes items not in source | */ -class HeaderList extends PropertyList { +class HeaderList extends ReadOnlyPropertyList { #req; #writable; @@ -152,49 +151,10 @@ class HeaderList extends PropertyList { } // ── Blocked inherited methods ───────────────────────────────────────── - // These are inherited from PropertyList/ReadOnlyPropertyList but are not - // part of the HeaderList API. They either use old naming or operate on - // the internal _items array instead of the request config. - - /** @throws {Error} Use get(name) or all() instead. */ - idx() { - throw new Error('idx() is not supported on HeaderList. Use get(name) instead.'); - } - - /** @throws {Error} Use append() instead. */ - add() { - throw new Error('add() is not supported on HeaderList. Use append() instead.'); - } - - /** @throws {Error} Use set() instead. */ - upsert() { - throw new Error('upsert() is not supported on HeaderList. Use set() instead.'); - } - - /** @throws {Error} Use delete() instead. */ - remove() { - throw new Error('remove() is not supported on HeaderList. Use delete() instead.'); - } - - /** @throws {Error} Use forEach() instead. */ - each() { - throw new Error('each() is not supported on HeaderList. Use forEach() instead.'); - } - - /** @throws {Error} Not supported — headers are stored as a plain object. */ - prepend() { - throw new Error('prepend() is not supported on HeaderList. Use append() or set() instead.'); - } - - /** @throws {Error} Not supported — headers are stored as a plain object. */ - insert() { - throw new Error('insert() is not supported on HeaderList. Use append() or set() instead.'); - } - - /** @throws {Error} Not supported — headers are stored as a plain object. */ - insertAfter() { - throw new Error('insertAfter() is not supported on HeaderList. Use append() or set() instead.'); - } + // These are inherited from ReadOnlyPropertyList but are not part of + // the HeaderList API. Set to undefined so they are not callable. + idx = undefined; + each = undefined; // ── Read method overrides (case-insensitive) ────────────────────────── diff --git a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js index 0188e0d2005..23027d3b6c8 100644 --- a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js +++ b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-request.js @@ -197,7 +197,7 @@ const addBrunoRequestShimToContext = (vm, req) => { // Wrapped in a block to avoid const redeclaration conflicts with other evalCode blocks // The bridge generates `each` (shared with CookieList); alias `forEach` for HeaderList's MDN-style API if (headersEvalCode) { - vm.evalCode(`{ ${headersEvalCode} globalThis.req.headerList.forEach = globalThis.req.headerList.each; }`); + vm.evalCode(`{ ${headersEvalCode} globalThis.req.headerList.forEach = globalThis.req.headerList.each; delete globalThis.req.headerList.each; }`); } }; diff --git a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js index 142d1903bd1..93b9ebcd85e 100644 --- a/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js +++ b/packages/bruno-js/src/sandbox/quickjs/shims/bruno-response.js @@ -133,7 +133,7 @@ const addBrunoResponseShimToContext = (vm, res) => { // Wrapped in a block to avoid const redeclaration conflicts with req.headerList's evalCode // The bridge generates `each` (shared with CookieList); alias `forEach` for HeaderList's MDN-style API if (resHeadersEvalCode) { - vm.evalCode(`{ ${resHeadersEvalCode} globalThis.res.headerList.forEach = globalThis.res.headerList.each; }`); + vm.evalCode(`{ ${resHeadersEvalCode} globalThis.res.headerList.forEach = globalThis.res.headerList.each; delete globalThis.res.headerList.each; }`); } }; diff --git a/packages/bruno-js/tests/header-list.spec.js b/packages/bruno-js/tests/header-list.spec.js index 61f4780c4e4..6bb1614d5ba 100644 --- a/packages/bruno-js/tests/header-list.spec.js +++ b/packages/bruno-js/tests/header-list.spec.js @@ -1,5 +1,4 @@ const HeaderList = require('../src/header-list'); -const PropertyList = require('../src/property-list'); const ReadOnlyPropertyList = require('../src/readonly-property-list'); const BrunoRequest = require('../src/bruno-request'); const BrunoResponse = require('../src/bruno-response'); @@ -19,10 +18,9 @@ describe('HeaderList (req.headerList)', () => { // ── Inheritance ──────────────────────────────────────────────────────── - test('extends PropertyList and ReadOnlyPropertyList', () => { + test('extends ReadOnlyPropertyList', () => { const { list } = createReqHeaders(); expect(list).toBeInstanceOf(ReadOnlyPropertyList); - expect(list).toBeInstanceOf(PropertyList); expect(list).toBeInstanceOf(HeaderList); }); From a632937c910ceadd9dfa3805280a43af94031fde Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 6 May 2026 16:12:44 +0530 Subject: [PATCH 5/6] test: add translations for pm.request.headers methods in request tests - Introduced new tests to validate the translation of pm.request.headers methods (prepend, insert, insertAfter) to their corresponding req.headerList.append method. - Enhanced existing tests to ensure accurate conversion and functionality of header management in the Bruno converters. --- .../transpiler-tests/request.test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js b/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js index 01f8ff0c3e8..e3a53388666 100644 --- a/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js +++ b/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js @@ -201,6 +201,24 @@ describe('Request Translation', () => { expect(translatedCode).toBe('req.headerList.clear();'); }); + it('should translate pm.request.headers.prepend to req.headerList.append', () => { + const code = 'pm.request.headers.prepend({key: "X-First", value: "1"});'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('req.headerList.append({key: "X-First", value: "1"});'); + }); + + it('should translate pm.request.headers.insert to req.headerList.append', () => { + const code = 'pm.request.headers.insert({key: "X-Mid", value: "2"}, "ref");'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('req.headerList.append({key: "X-Mid", value: "2"}, "ref");'); + }); + + it('should translate pm.request.headers.insertAfter to req.headerList.append', () => { + const code = 'pm.request.headers.insertAfter({key: "X-After", value: "3"}, "ref");'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('req.headerList.append({key: "X-After", value: "3"}, "ref");'); + }); + it('should translate pm.request.headers.toObject to req.headerList.toObject', () => { const code = 'const obj = pm.request.headers.toObject();'; const translatedCode = translateCode(code); From c9805d60193a4bb45d853a4df19c6baba3155e44 Mon Sep 17 00:00:00 2001 From: sanish-bruno Date: Wed, 6 May 2026 18:16:46 +0530 Subject: [PATCH 6/6] feat: enhance header translation methods for pm.request.headers - Added translations for additional pm.request.headers methods (get, has, one, all, count, indexOf, find, filter, each, map, reduce, toObject, clear) to their corresponding req.headerList methods. - Updated tests to validate the new translations and ensure accurate header management functionality in the Bruno converters. --- .../src/postman/postman-translations.js | 40 +++++++++++++++++++ .../src/utils/bruno-to-postman-translator.js | 4 ++ .../src/utils/postman-to-bruno-translator.js | 34 ++++++++++++++-- .../request.test.js | 12 ++++++ .../transpiler-tests/request.test.js | 20 ++++++++-- .../transpiler-tests/response.test.js | 12 ++++++ 6 files changed, 114 insertions(+), 8 deletions(-) diff --git a/packages/bruno-converters/src/postman/postman-translations.js b/packages/bruno-converters/src/postman/postman-translations.js index 1e96c2e9b42..0482aaae8cf 100644 --- a/packages/bruno-converters/src/postman/postman-translations.js +++ b/packages/bruno-converters/src/postman/postman-translations.js @@ -34,8 +34,48 @@ const replacements = { 'pm\\.environment\\.toObject\\(': 'bru.getAllEnvVars(', 'pm\\.environment\\.clear\\(': 'bru.deleteAllEnvVars(', 'pm\\.variables\\.toObject\\(': 'bru.getAllVars(', + // Request header PropertyList methods 'pm\\.request\\.headers\\.remove\\(': 'req.deleteHeader(', + 'pm\\.request\\.headers\\.get\\(': 'req.headerList.get(', + 'pm\\.request\\.headers\\.has\\(': 'req.headerList.has(', + 'pm\\.request\\.headers\\.one\\(': 'req.headerList.one(', + 'pm\\.request\\.headers\\.all\\(': 'req.headerList.all(', + 'pm\\.request\\.headers\\.count\\(': 'req.headerList.count(', + 'pm\\.request\\.headers\\.indexOf\\(': 'req.headerList.indexOf(', + 'pm\\.request\\.headers\\.find\\(': 'req.headerList.find(', + 'pm\\.request\\.headers\\.filter\\(': 'req.headerList.filter(', + 'pm\\.request\\.headers\\.each\\(': 'req.headerList.forEach(', + 'pm\\.request\\.headers\\.map\\(': 'req.headerList.map(', + 'pm\\.request\\.headers\\.reduce\\(': 'req.headerList.reduce(', + 'pm\\.request\\.headers\\.toObject\\(': 'req.headerList.toObject(', + 'pm\\.request\\.headers\\.clear\\(': 'req.headerList.clear(', + 'pm\\.request\\.headers\\.add\\(': 'req.headerList.append(', + 'pm\\.request\\.headers\\.upsert\\(': 'req.headerList.set(', + 'pm\\.request\\.headers\\.toString\\(': 'req.headerList.toString(', + 'pm\\.request\\.headers\\.toJSON\\(': 'req.headerList.toJSON(', + 'pm\\.request\\.headers\\.populate\\(': 'req.headerList.populate(', + 'pm\\.request\\.headers\\.repopulate\\(': 'req.headerList.repopulate(', + 'pm\\.request\\.headers\\.assimilate\\(': 'req.headerList.assimilate(', + // Lossy: positional inserts map to append (position irrelevant for headers) + // Note: regex can't drop the second arg, so it passes through as-is + 'pm\\.request\\.headers\\.prepend\\(': 'req.headerList.append(', + 'pm\\.request\\.headers\\.insert\\(': 'req.headerList.append(', + 'pm\\.request\\.headers\\.insertAfter\\(': 'req.headerList.append(', + // Response header PropertyList methods 'pm\\.response\\.headers\\.get\\(': 'res.getHeader(', + 'pm\\.response\\.headers\\.has\\(': 'res.headerList.has(', + 'pm\\.response\\.headers\\.one\\(': 'res.headerList.one(', + 'pm\\.response\\.headers\\.all\\(': 'res.headerList.all(', + 'pm\\.response\\.headers\\.count\\(': 'res.headerList.count(', + 'pm\\.response\\.headers\\.indexOf\\(': 'res.headerList.indexOf(', + 'pm\\.response\\.headers\\.find\\(': 'res.headerList.find(', + 'pm\\.response\\.headers\\.filter\\(': 'res.headerList.filter(', + 'pm\\.response\\.headers\\.each\\(': 'res.headerList.forEach(', + 'pm\\.response\\.headers\\.map\\(': 'res.headerList.map(', + 'pm\\.response\\.headers\\.reduce\\(': 'res.headerList.reduce(', + 'pm\\.response\\.headers\\.toObject\\(': 'res.headerList.toObject(', + 'pm\\.response\\.headers\\.toString\\(': 'res.headerList.toString(', + 'pm\\.response\\.headers\\.toJSON\\(': 'res.headerList.toJSON(', 'pm\\.response\\.to\\.have\\.jsonSchema\\(': 'expect(res.getBody()).to.have.jsonSchema(', 'pm\\.response\\.to\\.not\\.have\\.jsonSchema\\(': 'expect(res.getBody()).to.not.have.jsonSchema(', 'pm\\.response\\.not\\.to\\.have\\.jsonSchema\\(': 'expect(res.getBody()).not.to.have.jsonSchema(', diff --git a/packages/bruno-converters/src/utils/bruno-to-postman-translator.js b/packages/bruno-converters/src/utils/bruno-to-postman-translator.js index 65fc2bbca7e..f77f862dfd9 100644 --- a/packages/bruno-converters/src/utils/bruno-to-postman-translator.js +++ b/packages/bruno-converters/src/utils/bruno-to-postman-translator.js @@ -90,6 +90,8 @@ const simpleTranslations = { 'req.headerList.map': 'pm.request.headers.map', 'req.headerList.reduce': 'pm.request.headers.reduce', 'req.headerList.toObject': 'pm.request.headers.toObject', + 'req.headerList.toString': 'pm.request.headers.toString', + 'req.headerList.toJSON': 'pm.request.headers.toJSON', 'req.headerList.append': 'pm.request.headers.add', 'req.headerList.set': 'pm.request.headers.upsert', 'req.headerList.delete': 'pm.request.headers.remove', @@ -130,6 +132,8 @@ const simpleTranslations = { 'res.headerList.map': 'pm.response.headers.map', 'res.headerList.reduce': 'pm.response.headers.reduce', 'res.headerList.toObject': 'pm.response.headers.toObject', + 'res.headerList.toString': 'pm.response.headers.toString', + 'res.headerList.toJSON': 'pm.response.headers.toJSON', // Cookies jar 'bru.cookies.jar': 'pm.cookies.jar', diff --git a/packages/bruno-converters/src/utils/postman-to-bruno-translator.js b/packages/bruno-converters/src/utils/postman-to-bruno-translator.js index 70b4863dc41..65ae1fac104 100644 --- a/packages/bruno-converters/src/utils/postman-to-bruno-translator.js +++ b/packages/bruno-converters/src/utils/postman-to-bruno-translator.js @@ -65,11 +65,9 @@ const simpleTranslations = { 'pm.request.headers.map': 'req.headerList.map', 'pm.request.headers.reduce': 'req.headerList.reduce', 'pm.request.headers.toObject': 'req.headerList.toObject', + 'pm.request.headers.toString': 'req.headerList.toString', + 'pm.request.headers.toJSON': 'req.headerList.toJSON', 'pm.request.headers.clear': 'req.headerList.clear', - // Lossy: positional inserts map to append (position irrelevant for headers) - 'pm.request.headers.prepend': 'req.headerList.append', - 'pm.request.headers.insert': 'req.headerList.append', - 'pm.request.headers.insertAfter': 'req.headerList.append', // Response headers PropertyList methods (read-only) 'pm.response.headers.has': 'res.headerList.has', @@ -83,6 +81,8 @@ const simpleTranslations = { 'pm.response.headers.map': 'res.headerList.map', 'pm.response.headers.reduce': 'res.headerList.reduce', 'pm.response.headers.toObject': 'res.headerList.toObject', + 'pm.response.headers.toString': 'res.headerList.toString', + 'pm.response.headers.toJSON': 'res.headerList.toJSON', // Request properties (pm.request.*) 'pm.request.url.getHost': 'req.getHost', @@ -413,6 +413,32 @@ const complexTransformations = [ } }, + // Lossy: positional header inserts → append (only keep the first arg, drop positional ref) + // pm.request.headers.prepend(item) -> req.headerList.append(item) + { + pattern: 'pm.request.headers.prepend', + transform: (path, j) => { + const args = path.parent.value.arguments; + return j.callExpression(j.identifier('req.headerList.append'), args.length > 0 ? [args[0]] : []); + } + }, + // pm.request.headers.insert(item, before) -> req.headerList.append(item) + { + pattern: 'pm.request.headers.insert', + transform: (path, j) => { + const args = path.parent.value.arguments; + return j.callExpression(j.identifier('req.headerList.append'), args.length > 0 ? [args[0]] : []); + } + }, + // pm.request.headers.insertAfter(item, after) -> req.headerList.append(item) + { + pattern: 'pm.request.headers.insertAfter', + transform: (path, j) => { + const args = path.parent.value.arguments; + return j.callExpression(j.identifier('req.headerList.append'), args.length > 0 ? [args[0]] : []); + } + }, + // pm.response.to.be.ok -> expect(res.getStatus()).to.be.within(200, 299) { pattern: 'pm.response.to.be.ok', diff --git a/packages/bruno-converters/tests/bruno/bruno-to-postman-translations/request.test.js b/packages/bruno-converters/tests/bruno/bruno-to-postman-translations/request.test.js index 63305a3285f..3a38779ef69 100644 --- a/packages/bruno-converters/tests/bruno/bruno-to-postman-translations/request.test.js +++ b/packages/bruno-converters/tests/bruno/bruno-to-postman-translations/request.test.js @@ -292,6 +292,18 @@ console.log("Headers:", JSON.stringify(pm.request.headers)); expect(translatedCode).toBe('const obj = pm.request.headers.toObject();'); }); + it('should translate req.headerList.toString to pm.request.headers.toString', () => { + const code = 'const str = req.headerList.toString();'; + const translatedCode = translateBruToPostman(code); + expect(translatedCode).toBe('const str = pm.request.headers.toString();'); + }); + + it('should translate req.headerList.toJSON to pm.request.headers.toJSON', () => { + const code = 'const json = req.headerList.toJSON();'; + const translatedCode = translateBruToPostman(code); + expect(translatedCode).toBe('const json = pm.request.headers.toJSON();'); + }); + it('should translate req.headerList.set to pm.request.headers.upsert', () => { const code = 'req.headerList.set({key: "X-Custom", value: "updated"});'; const translatedCode = translateBruToPostman(code); diff --git a/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js b/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js index e3a53388666..bd057524078 100644 --- a/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js +++ b/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js @@ -207,16 +207,16 @@ describe('Request Translation', () => { expect(translatedCode).toBe('req.headerList.append({key: "X-First", value: "1"});'); }); - it('should translate pm.request.headers.insert to req.headerList.append', () => { + it('should translate pm.request.headers.insert to req.headerList.append (drops positional ref)', () => { const code = 'pm.request.headers.insert({key: "X-Mid", value: "2"}, "ref");'; const translatedCode = translateCode(code); - expect(translatedCode).toBe('req.headerList.append({key: "X-Mid", value: "2"}, "ref");'); + expect(translatedCode).toBe('req.headerList.append({key: "X-Mid", value: "2"});'); }); - it('should translate pm.request.headers.insertAfter to req.headerList.append', () => { + it('should translate pm.request.headers.insertAfter to req.headerList.append (drops positional ref)', () => { const code = 'pm.request.headers.insertAfter({key: "X-After", value: "3"}, "ref");'; const translatedCode = translateCode(code); - expect(translatedCode).toBe('req.headerList.append({key: "X-After", value: "3"}, "ref");'); + expect(translatedCode).toBe('req.headerList.append({key: "X-After", value: "3"});'); }); it('should translate pm.request.headers.toObject to req.headerList.toObject', () => { @@ -224,4 +224,16 @@ describe('Request Translation', () => { const translatedCode = translateCode(code); expect(translatedCode).toBe('const obj = req.headerList.toObject();'); }); + + it('should translate pm.request.headers.toString to req.headerList.toString', () => { + const code = 'const str = pm.request.headers.toString();'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('const str = req.headerList.toString();'); + }); + + it('should translate pm.request.headers.toJSON to req.headerList.toJSON', () => { + const code = 'const json = pm.request.headers.toJSON();'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('const json = req.headerList.toJSON();'); + }); }); diff --git a/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js b/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js index 5a08a540dd8..fdc70673e3d 100644 --- a/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js +++ b/packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js @@ -894,4 +894,16 @@ describe('Response Translation', () => { const translatedCode = translateCode(code); expect(translatedCode).toBe('const obj = res.headerList.toObject();'); }); + + it('should translate pm.response.headers.toString to res.headerList.toString', () => { + const code = 'const str = pm.response.headers.toString();'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('const str = res.headerList.toString();'); + }); + + it('should translate pm.response.headers.toJSON to res.headerList.toJSON', () => { + const code = 'const json = pm.response.headers.toJSON();'; + const translatedCode = translateCode(code); + expect(translatedCode).toBe('const json = res.headerList.toJSON();'); + }); });