mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
feat: implement item sorting for Postman export (#7581)
- Added functions to sort items by sequence and name, ensuring folders are prioritized over requests in the export output. - Enhanced the `brunoToPostman` function to utilize the new sorting logic. - Introduced comprehensive tests to validate the sorting behavior for folders and requests, including nested structures.
This commit is contained in:
@@ -2,6 +2,51 @@ import map from 'lodash/map';
|
||||
import { deleteSecretsInEnvs, deleteUidsInEnvs, deleteUidsInItems, isItemARequest } from '../common';
|
||||
import translateBruToPostman from '../utils/bruno-to-postman-translator';
|
||||
|
||||
const isItemAFolder = (item) => item.type === 'folder';
|
||||
|
||||
const sortItemsBySequence = (items) => [...items].sort((a, b) => a.seq - b.seq);
|
||||
|
||||
const sortByNameThenSequence = (items) => {
|
||||
const isSeqValid = (seq) => Number.isFinite(seq) && Number.isInteger(seq) && seq > 0;
|
||||
|
||||
const alphabeticallySorted = [...items].sort((a, b) => a.name && b.name && a.name.localeCompare(b.name));
|
||||
|
||||
const withoutSeq = alphabeticallySorted.filter((f) => !isSeqValid(f['seq']));
|
||||
const withSeq = alphabeticallySorted.filter((f) => isSeqValid(f['seq'])).sort((a, b) => a.seq - b.seq);
|
||||
|
||||
const sortedItems = withoutSeq;
|
||||
|
||||
withSeq.forEach((item) => {
|
||||
const position = item.seq - 1;
|
||||
const existingItem = withoutSeq[position];
|
||||
|
||||
const hasItemWithSameSeq = Array.isArray(existingItem)
|
||||
? existingItem?.[0]?.seq === item.seq
|
||||
: existingItem?.seq === item.seq;
|
||||
|
||||
if (hasItemWithSameSeq) {
|
||||
const newGroup = Array.isArray(existingItem) ? [...existingItem, item] : [existingItem, item];
|
||||
withoutSeq.splice(position, 1, newGroup);
|
||||
} else {
|
||||
withoutSeq.splice(position, 0, item);
|
||||
}
|
||||
});
|
||||
|
||||
return sortedItems.flat();
|
||||
};
|
||||
|
||||
const sortItemsForExport = (items) => {
|
||||
if (!items || !Array.isArray(items)) return [];
|
||||
|
||||
const folders = items.filter((item) => item && isItemAFolder(item));
|
||||
const requests = items.filter((item) => item && isItemARequest(item));
|
||||
|
||||
const sortedFolders = sortByNameThenSequence(folders);
|
||||
const sortedRequests = sortItemsBySequence(requests);
|
||||
|
||||
return [...sortedFolders, ...sortedRequests];
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms a given URL string into an object representing the protocol, host, path, query, and variables.
|
||||
*
|
||||
@@ -497,7 +542,9 @@ export const brunoToPostman = (collection) => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return map(itemsArray, (item) => {
|
||||
const sortedItems = sortItemsForExport(itemsArray);
|
||||
|
||||
return map(sortedItems, (item) => {
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -937,3 +937,113 @@ describe('brunoToPostman event handling', () => {
|
||||
expect(nestedRequest.event[0].script.exec).toEqual(['console.log("nested pre");']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('brunoToPostman item ordering', () => {
|
||||
const makeRequest = (name, seq) => ({
|
||||
type: 'http-request',
|
||||
name,
|
||||
seq,
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: 'https://example.com',
|
||||
headers: [],
|
||||
params: [],
|
||||
body: { mode: 'none' },
|
||||
auth: { mode: 'none' }
|
||||
}
|
||||
});
|
||||
|
||||
const makeFolder = (name, seq, items = []) => ({
|
||||
type: 'folder',
|
||||
name,
|
||||
seq,
|
||||
items
|
||||
});
|
||||
|
||||
it('should place folders before requests in export output', () => {
|
||||
const collection = {
|
||||
items: [
|
||||
makeRequest('Request A', 1),
|
||||
makeFolder('Folder B'),
|
||||
makeRequest('Request C', 2),
|
||||
makeFolder('Folder A')
|
||||
]
|
||||
};
|
||||
|
||||
const result = brunoToPostman(collection);
|
||||
const names = result.item.map((i) => i.name);
|
||||
|
||||
// Folders first (alphabetical since no seq), then requests (by seq)
|
||||
expect(names[0]).toBe('Folder A');
|
||||
expect(names[1]).toBe('Folder B');
|
||||
expect(names[2]).toBe('Request A');
|
||||
expect(names[3]).toBe('Request C');
|
||||
});
|
||||
|
||||
it('should sort requests by seq ascending', () => {
|
||||
const collection = {
|
||||
items: [
|
||||
makeRequest('Third', 3),
|
||||
makeRequest('First', 1),
|
||||
makeRequest('Second', 2)
|
||||
]
|
||||
};
|
||||
|
||||
const result = brunoToPostman(collection);
|
||||
const names = result.item.map((i) => i.name);
|
||||
|
||||
expect(names).toEqual(['First', 'Second', 'Third']);
|
||||
});
|
||||
|
||||
it('should sort folders by name then sequence', () => {
|
||||
const collection = {
|
||||
items: [
|
||||
makeFolder('Gamma', undefined),
|
||||
makeFolder('Alpha', undefined),
|
||||
makeFolder('Beta', 1)
|
||||
]
|
||||
};
|
||||
|
||||
const result = brunoToPostman(collection);
|
||||
const names = result.item.map((i) => i.name);
|
||||
|
||||
// Beta has seq=1, so it goes to position 0; Alpha and Gamma are alphabetical
|
||||
expect(names[0]).toBe('Beta');
|
||||
expect(names[1]).toBe('Alpha');
|
||||
expect(names[2]).toBe('Gamma');
|
||||
});
|
||||
|
||||
it('should sort items recursively within nested folders', () => {
|
||||
const collection = {
|
||||
items: [
|
||||
makeFolder('Parent', 1, [
|
||||
makeRequest('Nested C', 3),
|
||||
makeFolder('Nested Folder', 1),
|
||||
makeRequest('Nested A', 1)
|
||||
])
|
||||
]
|
||||
};
|
||||
|
||||
const result = brunoToPostman(collection);
|
||||
const parent = result.item[0];
|
||||
const nestedNames = parent.item.map((i) => i.name);
|
||||
|
||||
// Folder first, then requests sorted by seq
|
||||
expect(nestedNames).toEqual(['Nested Folder', 'Nested A', 'Nested C']);
|
||||
});
|
||||
|
||||
it('should handle folders without seq (older collections) alphabetically', () => {
|
||||
const collection = {
|
||||
items: [
|
||||
makeFolder('Zebra', undefined),
|
||||
makeFolder('Apple', undefined),
|
||||
makeFolder('Mango', undefined)
|
||||
]
|
||||
};
|
||||
|
||||
const result = brunoToPostman(collection);
|
||||
const names = result.item.map((i) => i.name);
|
||||
|
||||
expect(names).toEqual(['Apple', 'Mango', 'Zebra']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user