Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions packages/bruno-app/src/utils/codemirror/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ const STATIC_API_HINTS = {
'req.headerList.find(fn)',
'req.headerList.filter(fn)',
'req.headerList.indexOf(item)',
'req.headerList.forEach(fn)',
'req.headerList.each(fn)',
'req.headerList.map(fn)',
'req.headerList.reduce(fn, initialValue)',
'req.headerList.toObject()',
'req.headerList.toString()',
'req.headerList.toJSON()',
'req.headerList.append(headerObj)',
'req.headerList.set(name, value)',
'req.headerList.delete(predicate)',
'req.headerList.add(headerObj)',
'req.headerList.upsert(headerObj)',
'req.headerList.remove(predicate)',
'req.headerList.clear()',
'req.headerList.populate(items)',
'req.headerList.repopulate(items)',
Expand Down Expand Up @@ -93,7 +93,7 @@ const STATIC_API_HINTS = {
'res.headerList.find(fn)',
'res.headerList.filter(fn)',
'res.headerList.indexOf(item)',
'res.headerList.forEach(fn)',
'res.headerList.each(fn)',
'res.headerList.map(fn)',
'res.headerList.reduce(fn, initialValue)',
'res.headerList.toObject()',
Expand Down
16 changes: 8 additions & 8 deletions packages/bruno-converters/src/postman/postman-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ const replacements = {
'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\\.each\\(': 'req.headerList.each(',
'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\\.add\\(': 'req.headerList.add(',
'pm\\.request\\.headers\\.upsert\\(': 'req.headerList.upsert(',
'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)
// Lossy: positional inserts map to add (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(',
'pm\\.request\\.headers\\.prepend\\(': 'req.headerList.add(',
'pm\\.request\\.headers\\.insert\\(': 'req.headerList.add(',
'pm\\.request\\.headers\\.insertAfter\\(': 'req.headerList.add(',
// Response header PropertyList methods
'pm\\.response\\.headers\\.get\\(': 'res.getHeader(',
'pm\\.response\\.headers\\.has\\(': 'res.headerList.has(',
Expand All @@ -70,7 +70,7 @@ const replacements = {
'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\\.each\\(': 'res.headerList.each(',
'pm\\.response\\.headers\\.map\\(': 'res.headerList.map(',
'pm\\.response\\.headers\\.reduce\\(': 'res.headerList.reduce(',
'pm\\.response\\.headers\\.toObject\\(': 'res.headerList.toObject(',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ const simpleTranslations = {
'req.headerList.indexOf': 'pm.request.headers.indexOf',
'req.headerList.find': 'pm.request.headers.find',
'req.headerList.filter': 'pm.request.headers.filter',
'req.headerList.forEach': 'pm.request.headers.each',
'req.headerList.each': 'pm.request.headers.each',
'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',
'req.headerList.add': 'pm.request.headers.add',
'req.headerList.upsert': 'pm.request.headers.upsert',
'req.headerList.remove': 'pm.request.headers.remove',
'req.headerList.clear': 'pm.request.headers.clear',
'req.headerList.populate': 'pm.request.headers.populate',
'req.headerList.repopulate': 'pm.request.headers.repopulate',
Expand Down Expand Up @@ -128,7 +128,7 @@ const simpleTranslations = {
'res.headerList.indexOf': 'pm.response.headers.indexOf',
'res.headerList.find': 'pm.response.headers.find',
'res.headerList.filter': 'pm.response.headers.filter',
'res.headerList.forEach': 'pm.response.headers.each',
'res.headerList.each': 'pm.response.headers.each',
'res.headerList.map': 'pm.response.headers.map',
'res.headerList.reduce': 'pm.response.headers.reduce',
'res.headerList.toObject': 'pm.response.headers.toObject',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const simpleTranslations = {
'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.each': 'req.headerList.each',
'pm.request.headers.map': 'req.headerList.map',
'pm.request.headers.reduce': 'req.headerList.reduce',
'pm.request.headers.toObject': 'req.headerList.toObject',
Expand All @@ -77,7 +77,7 @@ const simpleTranslations = {
'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.each': 'res.headerList.each',
'pm.response.headers.map': 'res.headerList.map',
'pm.response.headers.reduce': 'res.headerList.reduce',
'pm.response.headers.toObject': 'res.headerList.toObject',
Expand Down Expand Up @@ -414,28 +414,28 @@ const complexTransformations = [
},

// Lossy: positional header inserts → append (only keep the first arg, drop positional ref)
// pm.request.headers.prepend(item) -> req.headerList.append(item)
// pm.request.headers.prepend(item) -> req.headerList.add(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]] : []);
return j.callExpression(j.identifier('req.headerList.add'), args.length > 0 ? [args[0]] : []);
}
},
// pm.request.headers.insert(item, before) -> req.headerList.append(item)
// pm.request.headers.insert(item, before) -> req.headerList.add(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]] : []);
return j.callExpression(j.identifier('req.headerList.add'), args.length > 0 ? [args[0]] : []);
}
},
// pm.request.headers.insertAfter(item, after) -> req.headerList.append(item)
// pm.request.headers.insertAfter(item, after) -> req.headerList.add(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]] : []);
return j.callExpression(j.identifier('req.headerList.add'), args.length > 0 ? [args[0]] : []);
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,14 @@ console.log("Headers:", JSON.stringify(pm.request.headers));
expect(translatedCode).toBe('const custom = pm.request.headers.filter(h => h.key.startsWith("X-"));');
});

it('should translate req.headerList.append to pm.request.headers.add', () => {
const code = 'req.headerList.append({key: "X-Custom", value: "test"});';
it('should translate req.headerList.add to pm.request.headers.add', () => {
const code = 'req.headerList.add({key: "X-Custom", value: "test"});';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.request.headers.add({key: "X-Custom", value: "test"});');
});

it('should translate req.headerList.delete to pm.request.headers.remove', () => {
const code = 'req.headerList.delete("Authorization");';
it('should translate req.headerList.remove to pm.request.headers.remove', () => {
const code = 'req.headerList.remove("Authorization");';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.request.headers.remove("Authorization");');
});
Expand Down Expand Up @@ -304,8 +304,8 @@ console.log("Headers:", JSON.stringify(pm.request.headers));
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"});';
it('should translate req.headerList.upsert to pm.request.headers.upsert', () => {
const code = 'req.headerList.upsert({key: "X-Custom", value: "updated"});';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.request.headers.upsert({key: "X-Custom", value: "updated"});');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ describe('Request Translation', () => {
expect(translatedCode).toBe('const allHeaders = req.headerList.all();');
});

it('should translate pm.request.headers.each to req.headerList.forEach', () => {
it('should translate pm.request.headers.each to req.headerList.each', () => {
const code = 'pm.request.headers.each(h => console.log(h.key));';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('req.headerList.forEach(h => console.log(h.key));');
expect(translatedCode).toBe('req.headerList.each(h => console.log(h.key));');
});

it('should translate pm.request.headers.filter to req.headerList.filter', () => {
Expand All @@ -201,22 +201,22 @@ describe('Request Translation', () => {
expect(translatedCode).toBe('req.headerList.clear();');
});

it('should translate pm.request.headers.prepend to req.headerList.append', () => {
it('should translate pm.request.headers.prepend to req.headerList.add', () => {
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"});');
expect(translatedCode).toBe('req.headerList.add({key: "X-First", value: "1"});');
});

it('should translate pm.request.headers.insert to req.headerList.append (drops positional ref)', () => {
it('should translate pm.request.headers.insert to req.headerList.add (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"});');
expect(translatedCode).toBe('req.headerList.add({key: "X-Mid", value: "2"});');
});

it('should translate pm.request.headers.insertAfter to req.headerList.append (drops positional ref)', () => {
it('should translate pm.request.headers.insertAfter to req.headerList.add (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"});');
expect(translatedCode).toBe('req.headerList.add({key: "X-After", value: "3"});');
});

it('should translate pm.request.headers.toObject to req.headerList.toObject', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,10 +871,10 @@ describe('Response Translation', () => {
expect(translatedCode).toBe('const allHeaders = res.headerList.all();');
});

it('should translate pm.response.headers.each to res.headerList.forEach', () => {
it('should translate pm.response.headers.each to res.headerList.each', () => {
const code = 'pm.response.headers.each(h => console.log(h.key));';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('res.headerList.forEach(h => console.log(h.key));');
expect(translatedCode).toBe('res.headerList.each(h => console.log(h.key));');
});

it('should translate pm.response.headers.filter to res.headerList.filter', () => {
Expand Down
41 changes: 18 additions & 23 deletions packages/bruno-js/src/header-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const ReadOnlyPropertyList = require('./readonly-property-list');
*
* | Method | Description |
* |------------------------------|----------------------------------------------|
* | `forEach(fn, context?)` | Calls `fn(header, index)` for every header |
* | `each(fn, context?)` | Calls `fn(header, index)` for every header |
* | `map(fn, context?)` | Returns a new array of mapped values |
* | `reduce(fn, initial?, context?)` | Reduces headers to a single value |
*
Expand All @@ -69,9 +69,9 @@ const ReadOnlyPropertyList = require('./readonly-property-list');
*
* | Method | Description |
* |-----------------------------------|----------------------------------------------------------|
* | `append(headerObj\|name, value?)` | Sets a header; accepts `{key,value}`, `"Key: Value"`, or `(name, value)` |
* | `set(headerObj\|name, value?)` | Sets (or replaces) a header; returns true/false/null |
* | `delete(predicate, context?)` | Deletes header(s) by name, predicate, or object |
* | `add(headerObj\|name, value?)` | Sets a header; accepts `{key,value}`, `"Key: Value"`, or `(name, value)` |
* | `upsert(headerObj\|name, value?)` | Sets (or replaces) a header; returns true/false/null |
* | `remove(predicate, context?)` | Deletes header(s) by name, predicate, or object |
* | `clear()` | Removes **all** headers (enabled and disabled) |
* | `populate(items\|string)` | Adds items, skipping keys that already exist |
* | `repopulate(items)` | Clears all, then populates with new items |
Expand Down Expand Up @@ -151,10 +151,9 @@ class HeaderList extends ReadOnlyPropertyList {
}

// ── Blocked inherited methods ─────────────────────────────────────────
// These are inherited from ReadOnlyPropertyList but are not part of
// the HeaderList API. Set to undefined so they are not callable.
// idx is inherited from ReadOnlyPropertyList but not part of the
// HeaderList API. Set to undefined so it is not callable.
idx = undefined;
each = undefined;

// ── Read method overrides (case-insensitive) ──────────────────────────

Expand Down Expand Up @@ -215,7 +214,7 @@ class HeaderList extends ReadOnlyPropertyList {
// ── Iteration overrides (optional context binding) ─────────────────

/** @param {Function} fn @param {*} [context] */
forEach(fn, context) {
each(fn, context) {
super.each(context !== undefined ? fn.bind(context) : fn);
}

Expand Down Expand Up @@ -245,25 +244,21 @@ class HeaderList extends ReadOnlyPropertyList {
// ── Write methods (direct request config manipulation) ────────────────

/**
* Append a header. Accepts a { key, value } object, a "Key: Value" string,
* or two arguments (name, value).
*
* Note: Unlike MDN's Headers.append(), this does not create duplicate keys
* (Bruno does not support multiple headers with the same name). Instead it
* delegates to set(), which overwrites any existing header with the same key.
* Add a header. Accepts a { key, value } object, a "Key: Value" string,
* or two arguments (name, value). Delegates to upsert().
*
* @param {object|string} itemOrName - Header object, "Key: Value" string, or header name
* @param {string} [value] - Header value (when using two-arg form)
*/
append(itemOrName, value) {
add(itemOrName, value) {
if (typeof itemOrName === 'string' && value !== undefined) {
this.set({ key: itemOrName, value });
this.upsert({ key: itemOrName, value });
return;
}
if (typeof itemOrName === 'string') {
itemOrName = HeaderList.#parseHeaderString(itemOrName);
}
this.set(itemOrName);
this.upsert(itemOrName);
}

/**
Expand All @@ -273,7 +268,7 @@ class HeaderList extends ReadOnlyPropertyList {
* @param {string} [value] - Header value (when using two-arg form)
* @returns {boolean|null} `true` if added, `false` if updated, `null` if input was nil
*/
set(itemOrName, value) {
upsert(itemOrName, value) {
this.#assertWritable();
let item = itemOrName;
if (typeof itemOrName === 'string') {
Expand All @@ -300,12 +295,12 @@ class HeaderList extends ReadOnlyPropertyList {
}

/**
* Delete header(s) matching a predicate, key string, or item reference.
* Remove header(s) matching a predicate, key string, or item reference.
* String and object removal are case-insensitive.
* @param {Function|string|object} predicate
* @param {*} [context] - Bind `this` for function predicates
*/
delete(predicate, context) {
remove(predicate, context) {
this.#assertWritable();
if (typeof predicate === 'function') {
const bound = context !== undefined ? predicate.bind(context) : predicate;
Expand Down Expand Up @@ -403,15 +398,15 @@ class HeaderList extends ReadOnlyPropertyList {
for (const line of lines) {
const parsed = HeaderList.#parseHeaderString(line);
if (parsed && !this.has(parsed.key)) {
this.append(parsed);
this.add(parsed);
}
}
return;
}
const list = Array.isArray(items) ? items : [];
for (const item of list) {
if (item && item.key && !this.has(item.key)) {
this.append(item);
this.add(item);
}
}
}
Expand Down Expand Up @@ -480,7 +475,7 @@ class HeaderList extends ReadOnlyPropertyList {
}
// Merge source items into this list
for (const item of items) {
this.append(item);
this.add(item);
}
// Prune: remove items from this list that are not in source
if (prune && items.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const addBrunoRequestShimToContext = (vm, req) => {
globalPath: 'globalThis.req.headerList',
syncReadMethods: ['get', 'has', 'count', 'indexOf', 'toObject', 'toString'],
syncReadObjectMethods: ['one', 'all', 'toJSON'],
syncWriteMethods: ['append', 'set', 'delete', 'clear', 'populate', 'repopulate', 'assimilate'],
syncWriteMethods: ['add', 'upsert', 'remove', 'clear', 'populate', 'repopulate', 'assimilate'],
withIterators: true
});
vm.setProp(reqObject, 'headerList', headerListObj);
Expand Down Expand Up @@ -195,9 +195,8 @@ const addBrunoRequestShimToContext = (vm, req) => {

// Evaluate iterator code after req is on global (iterators reference globalThis.req.headerList)
// 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; delete globalThis.req.headerList.each; }`);
vm.evalCode(`{ ${headersEvalCode} }`);
}
};

Expand Down
Loading
Loading