Fix/export folder and collection level scripts (#5942)

* fix: bruno to postman export - export pre and post request scripts on folder/collection level

* refactor: removed redundant code.

* fix: lint error - file should end with a new line

---------

Co-authored-by: Jakub Sadowski <jakubsadowski08@gmail.com>
Co-authored-by: Bijin A B <bijin@usebruno.com>
This commit is contained in:
Abhishek S Lal
2025-10-30 19:54:07 +05:30
committed by GitHub
parent 21e8615247
commit f3afb4bf84
2 changed files with 137 additions and 23 deletions

View File

@@ -69,7 +69,7 @@ export const transformUrl = (url, params) => {
postmanUrl.query = params
.filter((param) => param.type === 'query')
.map(({ name, value, description }) => ({ key: name, value, description }));
// Construct path params.
postmanUrl.variable = params
.filter((param) => param.type === 'path')
@@ -80,10 +80,10 @@ export const transformUrl = (url, params) => {
/**
* Collapses multiple consecutive slashes (`//`) into a single slash, while skipping the protocol (e.g., `http://` or `https://`).
*
*
* @param {String} url - A URL string
* @returns {String} The sanitized URL
*
*
*/
const collapseDuplicateSlashes = (url) => {
return url.replace(/(?<!:)\/{2,}/g, '/');
@@ -91,7 +91,7 @@ const collapseDuplicateSlashes = (url) => {
/**
* Replaces all `\\` (backslashes) with `//` (forward slashes) and collapses multiple slashes into one.
*
*
* @param {string} url - The URL to sanitize.
* @returns {string} The sanitized URL.
*
@@ -146,24 +146,30 @@ export const brunoToPostman = (collection) => {
type: 'default'
}));
};
const generateEventSection = (item) => {
const eventArray = [];
if (item?.request?.tests?.length) {
eventArray.push({
listen: 'test',
script: {
exec: item.request.tests.split('\n')
// type: 'text/javascript'
}
});
}
if (item?.request?.script?.req) {
// Request: item.script, Folder: item.root.request.script, Collection: item.request.script
const scriptBlock = item?.script || item?.root?.request?.script || item?.request?.script;
if (scriptBlock?.req) {
eventArray.push({
listen: 'prerequest',
script: {
exec: item.request.script.req.split('\n')
// type: 'text/javascript'
type: 'text/javascript',
packages: {},
requests: {},
exec: scriptBlock.req.split('\n')
}
});
}
if (scriptBlock?.res) {
eventArray.push({
listen: 'test',
script: {
type: 'text/javascript',
packages: {},
requests: {},
exec: scriptBlock.res.split('\n')
}
});
}
@@ -317,7 +323,7 @@ export const brunoToPostman = (collection) => {
if (!itemRequest) {
return {};
}
const requestObject = {
method: itemRequest.method || 'GET',
header: generateHeaders(itemRequest.headers),
@@ -337,7 +343,7 @@ export const brunoToPostman = (collection) => {
if (!itemsArray || !Array.isArray(itemsArray)) {
return [];
}
return map(itemsArray, (item) => {
if (!item) {
return null;
@@ -346,17 +352,20 @@ export const brunoToPostman = (collection) => {
if (item.type === 'grpc-request') {
return null;
}
if (item.type === 'folder') {
const folderEvents = generateEventSection(item);
return {
name: item.name || 'Untitled Folder',
item: item.items && item.items.length ? generateItemSection(item.items) : []
item: generateItemSection(item.items),
...(folderEvents.length ? { event: folderEvents } : {})
};
} else {
const requestEvents = generateEventSection(item.request);
return {
name: item.name || 'Untitled Request',
event: generateEventSection(item),
request: generateRequestSection(item.request)
request: generateRequestSection(item.request),
...(requestEvents.length ? { event: requestEvents } : {})
};
}
});
@@ -365,6 +374,10 @@ export const brunoToPostman = (collection) => {
collectionToExport.info = generateInfoSection();
collectionToExport.item = generateItemSection(collection.items);
collectionToExport.variable = generateCollectionVars(collection);
const collectionEvents = generateEventSection(collection.root);
if (collectionEvents.length) {
collectionToExport.event = collectionEvents;
}
return collectionToExport;
};

View File

@@ -492,3 +492,104 @@ describe('brunoToPostman null checks and fallbacks', () => {
});
});
});
describe('brunoToPostman event handling', () => {
it('should generate events for request scripts (req/res)', () => {
const simpleCollection = {
items: [
{
name: 'Test Request',
type: 'http-request',
request: {
method: 'GET',
url: 'https://example.com',
script: {
req: 'console.log("pre");',
res: 'console.log("post");'
}
}
}
]
};
const result = brunoToPostman(simpleCollection);
const events = result.item[0].event;
expect(events).toHaveLength(2);
expect(events[0]).toMatchObject({ listen: 'prerequest', script: { exec: ['console.log("pre");'] } });
expect(events[1]).toMatchObject({ listen: 'test', script: { exec: ['console.log("post");'] } });
});
it('should generate events for folder scripts', () => {
const simpleCollection = {
items: [
{
type: 'folder',
name: 'Test Folder',
script: {
req: 'console.log("folder pre");',
res: 'console.log("folder post");'
},
items: []
}
]
};
const result = brunoToPostman(simpleCollection);
const folder = result.item[0];
expect(folder.name).toBe('Test Folder');
expect(folder.event).toHaveLength(2);
expect(folder.event[0].listen).toBe('prerequest');
expect(folder.event[1].listen).toBe('test');
});
it('should generate collection-level events from root', () => {
const simpleCollection = {
root: {
script: {
req: 'console.log("collection pre");',
res: 'console.log("collection post");'
}
},
items: []
};
const result = brunoToPostman(simpleCollection);
expect(result.event).toHaveLength(2);
expect(result.event[0].listen).toBe('prerequest');
expect(result.event[1].listen).toBe('test');
});
it('should handle nested folders and requests with scripts', () => {
const simpleCollection = {
items: [
{
type: 'folder',
name: 'Parent Folder',
items: [
{
type: 'http-request',
name: 'Nested Request',
request: {
method: 'GET',
url: 'https://example.com',
script: { req: 'console.log("nested pre");' }
}
}
]
}
]
};
const result = brunoToPostman(simpleCollection);
const folder = result.item[0];
const nestedRequest = folder.item[0];
expect(folder.name).toBe('Parent Folder');
expect(nestedRequest.name).toBe('Nested Request');
expect(nestedRequest.event).toHaveLength(1);
expect(nestedRequest.event[0].listen).toBe('prerequest');
expect(nestedRequest.event[0].script.exec).toEqual(['console.log("nested pre");']);
});
});