Skip to content

Commit f3afb4b

Browse files
abhishek-brunojakubsadowski08bijin-bruno
authored
Fix/export folder and collection level scripts (usebruno#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>
1 parent 21e8615 commit f3afb4b

File tree

2 files changed

+133
-19
lines changed

2 files changed

+133
-19
lines changed

packages/bruno-converters/src/postman/bruno-to-postman.js

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const transformUrl = (url, params) => {
6969
postmanUrl.query = params
7070
.filter((param) => param.type === 'query')
7171
.map(({ name, value, description }) => ({ key: name, value, description }));
72-
72+
7373
// Construct path params.
7474
postmanUrl.variable = params
7575
.filter((param) => param.type === 'path')
@@ -80,18 +80,18 @@ export const transformUrl = (url, params) => {
8080

8181
/**
8282
* Collapses multiple consecutive slashes (`//`) into a single slash, while skipping the protocol (e.g., `http://` or `https://`).
83-
*
83+
*
8484
* @param {String} url - A URL string
8585
* @returns {String} The sanitized URL
86-
*
86+
*
8787
*/
8888
const collapseDuplicateSlashes = (url) => {
8989
return url.replace(/(?<!:)\/{2,}/g, '/');
9090
};
9191

9292
/**
9393
* Replaces all `\\` (backslashes) with `//` (forward slashes) and collapses multiple slashes into one.
94-
*
94+
*
9595
* @param {string} url - The URL to sanitize.
9696
* @returns {string} The sanitized URL.
9797
*
@@ -146,24 +146,30 @@ export const brunoToPostman = (collection) => {
146146
type: 'default'
147147
}));
148148
};
149-
150149
const generateEventSection = (item) => {
151150
const eventArray = [];
152-
if (item?.request?.tests?.length) {
151+
// Request: item.script, Folder: item.root.request.script, Collection: item.request.script
152+
const scriptBlock = item?.script || item?.root?.request?.script || item?.request?.script;
153+
154+
if (scriptBlock?.req) {
153155
eventArray.push({
154-
listen: 'test',
156+
listen: 'prerequest',
155157
script: {
156-
exec: item.request.tests.split('\n')
157-
// type: 'text/javascript'
158+
type: 'text/javascript',
159+
packages: {},
160+
requests: {},
161+
exec: scriptBlock.req.split('\n')
158162
}
159163
});
160164
}
161-
if (item?.request?.script?.req) {
165+
if (scriptBlock?.res) {
162166
eventArray.push({
163-
listen: 'prerequest',
167+
listen: 'test',
164168
script: {
165-
exec: item.request.script.req.split('\n')
166-
// type: 'text/javascript'
169+
type: 'text/javascript',
170+
packages: {},
171+
requests: {},
172+
exec: scriptBlock.res.split('\n')
167173
}
168174
});
169175
}
@@ -317,7 +323,7 @@ export const brunoToPostman = (collection) => {
317323
if (!itemRequest) {
318324
return {};
319325
}
320-
326+
321327
const requestObject = {
322328
method: itemRequest.method || 'GET',
323329
header: generateHeaders(itemRequest.headers),
@@ -337,7 +343,7 @@ export const brunoToPostman = (collection) => {
337343
if (!itemsArray || !Array.isArray(itemsArray)) {
338344
return [];
339345
}
340-
346+
341347
return map(itemsArray, (item) => {
342348
if (!item) {
343349
return null;
@@ -346,17 +352,20 @@ export const brunoToPostman = (collection) => {
346352
if (item.type === 'grpc-request') {
347353
return null;
348354
}
349-
355+
350356
if (item.type === 'folder') {
357+
const folderEvents = generateEventSection(item);
351358
return {
352359
name: item.name || 'Untitled Folder',
353-
item: item.items && item.items.length ? generateItemSection(item.items) : []
360+
item: generateItemSection(item.items),
361+
...(folderEvents.length ? { event: folderEvents } : {})
354362
};
355363
} else {
364+
const requestEvents = generateEventSection(item.request);
356365
return {
357366
name: item.name || 'Untitled Request',
358-
event: generateEventSection(item),
359-
request: generateRequestSection(item.request)
367+
request: generateRequestSection(item.request),
368+
...(requestEvents.length ? { event: requestEvents } : {})
360369
};
361370
}
362371
});
@@ -365,6 +374,10 @@ export const brunoToPostman = (collection) => {
365374
collectionToExport.info = generateInfoSection();
366375
collectionToExport.item = generateItemSection(collection.items);
367376
collectionToExport.variable = generateCollectionVars(collection);
377+
const collectionEvents = generateEventSection(collection.root);
378+
if (collectionEvents.length) {
379+
collectionToExport.event = collectionEvents;
380+
}
368381
return collectionToExport;
369382
};
370383

packages/bruno-converters/tests/postman/bruno-to-postman.spec.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,104 @@ describe('brunoToPostman null checks and fallbacks', () => {
492492
});
493493
});
494494
});
495+
496+
describe('brunoToPostman event handling', () => {
497+
it('should generate events for request scripts (req/res)', () => {
498+
const simpleCollection = {
499+
items: [
500+
{
501+
name: 'Test Request',
502+
type: 'http-request',
503+
request: {
504+
method: 'GET',
505+
url: 'https://example.com',
506+
script: {
507+
req: 'console.log("pre");',
508+
res: 'console.log("post");'
509+
}
510+
}
511+
}
512+
]
513+
};
514+
515+
const result = brunoToPostman(simpleCollection);
516+
const events = result.item[0].event;
517+
518+
expect(events).toHaveLength(2);
519+
expect(events[0]).toMatchObject({ listen: 'prerequest', script: { exec: ['console.log("pre");'] } });
520+
expect(events[1]).toMatchObject({ listen: 'test', script: { exec: ['console.log("post");'] } });
521+
});
522+
523+
it('should generate events for folder scripts', () => {
524+
const simpleCollection = {
525+
items: [
526+
{
527+
type: 'folder',
528+
name: 'Test Folder',
529+
script: {
530+
req: 'console.log("folder pre");',
531+
res: 'console.log("folder post");'
532+
},
533+
items: []
534+
}
535+
]
536+
};
537+
538+
const result = brunoToPostman(simpleCollection);
539+
const folder = result.item[0];
540+
541+
expect(folder.name).toBe('Test Folder');
542+
expect(folder.event).toHaveLength(2);
543+
expect(folder.event[0].listen).toBe('prerequest');
544+
expect(folder.event[1].listen).toBe('test');
545+
});
546+
547+
it('should generate collection-level events from root', () => {
548+
const simpleCollection = {
549+
root: {
550+
script: {
551+
req: 'console.log("collection pre");',
552+
res: 'console.log("collection post");'
553+
}
554+
},
555+
items: []
556+
};
557+
558+
const result = brunoToPostman(simpleCollection);
559+
expect(result.event).toHaveLength(2);
560+
expect(result.event[0].listen).toBe('prerequest');
561+
expect(result.event[1].listen).toBe('test');
562+
});
563+
564+
it('should handle nested folders and requests with scripts', () => {
565+
const simpleCollection = {
566+
items: [
567+
{
568+
type: 'folder',
569+
name: 'Parent Folder',
570+
items: [
571+
{
572+
type: 'http-request',
573+
name: 'Nested Request',
574+
request: {
575+
method: 'GET',
576+
url: 'https://example.com',
577+
script: { req: 'console.log("nested pre");' }
578+
}
579+
}
580+
]
581+
}
582+
]
583+
};
584+
585+
const result = brunoToPostman(simpleCollection);
586+
const folder = result.item[0];
587+
const nestedRequest = folder.item[0];
588+
589+
expect(folder.name).toBe('Parent Folder');
590+
expect(nestedRequest.name).toBe('Nested Request');
591+
expect(nestedRequest.event).toHaveLength(1);
592+
expect(nestedRequest.event[0].listen).toBe('prerequest');
593+
expect(nestedRequest.event[0].script.exec).toEqual(['console.log("nested pre");']);
594+
});
595+
});

0 commit comments

Comments
 (0)