mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-02 00:54:09 +00:00
365 lines
10 KiB
JavaScript
365 lines
10 KiB
JavaScript
const { get, each, find, compact, filter } = require('lodash');
|
|
const os = require('os');
|
|
|
|
const mergeHeaders = (collection, request, requestTreePath) => {
|
|
let headers = new Map();
|
|
|
|
let collectionHeaders = get(collection, 'root.request.headers', []);
|
|
collectionHeaders.forEach((header) => {
|
|
if (header.enabled) {
|
|
headers.set(header.name, header.value);
|
|
if (header?.name?.toLowerCase() === 'content-type') {
|
|
contentTypeDefined = true;
|
|
}
|
|
}
|
|
});
|
|
|
|
for (let i of requestTreePath) {
|
|
if (i.type === 'folder') {
|
|
let _headers = get(i, 'root.request.headers', []);
|
|
_headers.forEach((header) => {
|
|
if (header.enabled) {
|
|
headers.set(header.name, header.value);
|
|
}
|
|
});
|
|
} else {
|
|
const _headers = i?.draft ? get(i, 'draft.request.headers', []) : get(i, 'request.headers', []);
|
|
_headers.forEach((header) => {
|
|
if (header.enabled) {
|
|
headers.set(header.name, header.value);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
request.headers = Array.from(headers, ([name, value]) => ({ name, value, enabled: true }));
|
|
};
|
|
|
|
const mergeVars = (collection, request, requestTreePath) => {
|
|
let reqVars = new Map();
|
|
let collectionRequestVars = get(collection, 'root.request.vars.req', []);
|
|
let collectionVariables = {};
|
|
collectionRequestVars.forEach((_var) => {
|
|
if (_var.enabled) {
|
|
reqVars.set(_var.name, _var.value);
|
|
collectionVariables[_var.name] = _var.value;
|
|
}
|
|
});
|
|
let folderVariables = {};
|
|
let requestVariables = {};
|
|
for (let i of requestTreePath) {
|
|
if (i.type === 'folder') {
|
|
let vars = get(i, 'root.request.vars.req', []);
|
|
vars.forEach((_var) => {
|
|
if (_var.enabled) {
|
|
reqVars.set(_var.name, _var.value);
|
|
folderVariables[_var.name] = _var.value;
|
|
}
|
|
});
|
|
} else {
|
|
const vars = i?.draft ? get(i, 'draft.request.vars.req', []) : get(i, 'request.vars.req', []);
|
|
vars.forEach((_var) => {
|
|
if (_var.enabled) {
|
|
reqVars.set(_var.name, _var.value);
|
|
requestVariables[_var.name] = _var.value;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
request.collectionVariables = collectionVariables;
|
|
request.folderVariables = folderVariables;
|
|
request.requestVariables = requestVariables;
|
|
|
|
if(request?.vars) {
|
|
request.vars.req = Array.from(reqVars, ([name, value]) => ({
|
|
name,
|
|
value,
|
|
enabled: true,
|
|
type: 'request'
|
|
}));
|
|
}
|
|
|
|
let resVars = new Map();
|
|
let collectionResponseVars = get(collection, 'root.request.vars.res', []);
|
|
collectionResponseVars.forEach((_var) => {
|
|
if (_var.enabled) {
|
|
resVars.set(_var.name, _var.value);
|
|
}
|
|
});
|
|
for (let i of requestTreePath) {
|
|
if (i.type === 'folder') {
|
|
let vars = get(i, 'root.request.vars.res', []);
|
|
vars.forEach((_var) => {
|
|
if (_var.enabled) {
|
|
resVars.set(_var.name, _var.value);
|
|
}
|
|
});
|
|
} else {
|
|
const vars = i?.draft ? get(i, 'draft.request.vars.res', []) : get(i, 'request.vars.res', []);
|
|
vars.forEach((_var) => {
|
|
if (_var.enabled) {
|
|
resVars.set(_var.name, _var.value);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if(request?.vars) {
|
|
request.vars.res = Array.from(resVars, ([name, value]) => ({
|
|
name,
|
|
value,
|
|
enabled: true,
|
|
type: 'response'
|
|
}));
|
|
}
|
|
};
|
|
|
|
const mergeScripts = (collection, request, requestTreePath, scriptFlow) => {
|
|
let collectionPreReqScript = get(collection, 'root.request.script.req', '');
|
|
let collectionPostResScript = get(collection, 'root.request.script.res', '');
|
|
let collectionTests = get(collection, 'root.request.tests', '');
|
|
|
|
let combinedPreReqScript = [];
|
|
let combinedPostResScript = [];
|
|
let combinedTests = [];
|
|
for (let i of requestTreePath) {
|
|
if (i.type === 'folder') {
|
|
let preReqScript = get(i, 'root.request.script.req', '');
|
|
if (preReqScript && preReqScript.trim() !== '') {
|
|
combinedPreReqScript.push(preReqScript);
|
|
}
|
|
|
|
let postResScript = get(i, 'root.request.script.res', '');
|
|
if (postResScript && postResScript.trim() !== '') {
|
|
combinedPostResScript.push(postResScript);
|
|
}
|
|
|
|
let tests = get(i, 'root.request.tests', '');
|
|
if (tests && tests?.trim?.() !== '') {
|
|
combinedTests.push(tests);
|
|
}
|
|
}
|
|
}
|
|
|
|
request.script.req = compact([collectionPreReqScript, ...combinedPreReqScript, request?.script?.req || '']).join(os.EOL);
|
|
|
|
if (scriptFlow === 'sequential') {
|
|
request.script.res = compact([collectionPostResScript, ...combinedPostResScript, request?.script?.res || '']).join(os.EOL);
|
|
} else {
|
|
request.script.res = compact([request?.script?.res || '', ...combinedPostResScript.reverse(), collectionPostResScript]).join(os.EOL);
|
|
}
|
|
|
|
if (scriptFlow === 'sequential') {
|
|
request.tests = compact([collectionTests, ...combinedTests, request?.tests || '']).join(os.EOL);
|
|
} else {
|
|
request.tests = compact([request?.tests || '', ...combinedTests.reverse(), collectionTests]).join(os.EOL);
|
|
}
|
|
};
|
|
|
|
const flattenItems = (items = []) => {
|
|
const flattenedItems = [];
|
|
|
|
const flatten = (itms, flattened) => {
|
|
each(itms, (i) => {
|
|
flattened.push(i);
|
|
|
|
if (i.items && i.items.length) {
|
|
flatten(i.items, flattened);
|
|
}
|
|
});
|
|
};
|
|
|
|
flatten(items, flattenedItems);
|
|
|
|
return flattenedItems;
|
|
};
|
|
|
|
const findItem = (items = [], itemUid) => {
|
|
return find(items, (i) => i.uid === itemUid);
|
|
};
|
|
|
|
const findItemInCollection = (collection, itemUid) => {
|
|
let flattenedItems = flattenItems(collection.items);
|
|
|
|
return findItem(flattenedItems, itemUid);
|
|
};
|
|
|
|
const findParentItemInCollection = (collection, itemUid) => {
|
|
let flattenedItems = flattenItems(collection.items);
|
|
|
|
return find(flattenedItems, (item) => {
|
|
return item.items && find(item.items, (i) => i.uid === itemUid);
|
|
});
|
|
};
|
|
|
|
const getTreePathFromCollectionToItem = (collection, _item) => {
|
|
let path = [];
|
|
let item = findItemInCollection(collection, _item.uid);
|
|
while (item) {
|
|
path.unshift(item);
|
|
item = findParentItemInCollection(collection, item.uid);
|
|
}
|
|
return path;
|
|
};
|
|
|
|
const slash = (path) => {
|
|
const isExtendedLengthPath = /^\\\\\?\\/.test(path);
|
|
if (isExtendedLengthPath) {
|
|
return path;
|
|
}
|
|
return path?.replace?.(/\\/g, '/');
|
|
};
|
|
|
|
const findItemByPathname = (items = [], pathname) => {
|
|
return find(items, (i) => slash(i.pathname) === slash(pathname));
|
|
};
|
|
|
|
const findItemInCollectionByPathname = (collection, pathname) => {
|
|
let flattenedItems = flattenItems(collection.items);
|
|
|
|
return findItemByPathname(flattenedItems, pathname);
|
|
};
|
|
|
|
const sortCollection = (collection) => {
|
|
const items = collection.items || [];
|
|
let folderItems = filter(items, (item) => item.type === 'folder');
|
|
let requestItems = filter(items, (item) => item.type !== 'folder');
|
|
|
|
folderItems = folderItems.sort((a, b) => a.name.localeCompare(b.name));
|
|
requestItems = requestItems.sort((a, b) => a.seq - b.seq);
|
|
|
|
collection.items = folderItems.concat(requestItems);
|
|
|
|
each(folderItems, (item) => {
|
|
sortCollection(item);
|
|
});
|
|
};
|
|
|
|
const sortFolder = (folder = {}) => {
|
|
const items = folder.items || [];
|
|
let folderItems = filter(items, (item) => item.type === 'folder');
|
|
let requestItems = filter(items, (item) => item.type !== 'folder');
|
|
|
|
folderItems = folderItems.sort((a, b) => a.name.localeCompare(b.name));
|
|
requestItems = requestItems.sort((a, b) => a.seq - b.seq);
|
|
|
|
folder.items = folderItems.concat(requestItems);
|
|
|
|
each(folderItems, (item) => {
|
|
sortFolder(item);
|
|
});
|
|
|
|
return folder;
|
|
};
|
|
|
|
const getAllRequestsInFolderRecursively = (folder = {}) => {
|
|
let requests = [];
|
|
|
|
if (folder.items && folder.items.length) {
|
|
folder.items.forEach((item) => {
|
|
if (item.type !== 'folder') {
|
|
requests.push(item);
|
|
} else {
|
|
requests = requests.concat(getAllRequestsInFolderRecursively(item));
|
|
}
|
|
});
|
|
}
|
|
|
|
return requests;
|
|
};
|
|
|
|
const getEnvVars = (environment = {}) => {
|
|
const variables = environment.variables;
|
|
if (!variables || !variables.length) {
|
|
return {
|
|
__name__: environment.name
|
|
};
|
|
}
|
|
|
|
const envVars = {};
|
|
each(variables, (variable) => {
|
|
if (variable.enabled) {
|
|
envVars[variable.name] = variable.value;
|
|
}
|
|
});
|
|
|
|
return {
|
|
...envVars,
|
|
__name__: environment.name
|
|
};
|
|
};
|
|
|
|
const getFormattedCollectionOauth2Credentials = ({ oauth2Credentials = [] }) => {
|
|
let credentialsVariables = {};
|
|
oauth2Credentials.forEach(({ credentialsId, credentials }) => {
|
|
if (credentials) {
|
|
Object.entries(credentials).forEach(([key, value]) => {
|
|
credentialsVariables[`$oauth2.${credentialsId}.${key}`] = value;
|
|
});
|
|
}
|
|
});
|
|
return credentialsVariables;
|
|
};
|
|
|
|
const mergeAuth = (collection, request, requestTreePath) => {
|
|
// Start with collection level auth (always consider collection auth as base)
|
|
let collectionAuth = get(collection, 'root.request.auth', { mode: 'none' });
|
|
let effectiveAuth = collectionAuth;
|
|
let lastFolderWithAuth = null;
|
|
|
|
// Traverse through the path to find the closest auth configuration
|
|
for (let i of requestTreePath) {
|
|
if (i.type === 'folder') {
|
|
const folderAuth = get(i, 'root.request.auth');
|
|
// Only consider folders that have a valid auth mode
|
|
if (folderAuth && folderAuth.mode && folderAuth.mode !== 'none' && folderAuth.mode !== 'inherit') {
|
|
effectiveAuth = folderAuth;
|
|
lastFolderWithAuth = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If request is set to inherit, use the effective auth from collection/folders
|
|
if (request.auth.mode === 'inherit') {
|
|
request.auth = effectiveAuth;
|
|
|
|
// For OAuth2, we need to handle credentials properly
|
|
if (effectiveAuth.mode === 'oauth2') {
|
|
if (lastFolderWithAuth) {
|
|
// If auth is from folder, add folderUid and clear itemUid
|
|
request.oauth2Credentials = {
|
|
...request.oauth2Credentials,
|
|
folderUid: lastFolderWithAuth.uid,
|
|
itemUid: null,
|
|
mode: request.auth.mode
|
|
};
|
|
} else {
|
|
// If auth is from collection, ensure no folderUid and no itemUid
|
|
request.oauth2Credentials = {
|
|
...request.oauth2Credentials,
|
|
folderUid: null,
|
|
itemUid: null,
|
|
mode: request.auth.mode
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
mergeHeaders,
|
|
mergeVars,
|
|
mergeScripts,
|
|
mergeAuth,
|
|
getTreePathFromCollectionToItem,
|
|
slash,
|
|
findItemByPathname,
|
|
findItemInCollection,
|
|
findItemInCollectionByPathname,
|
|
sortCollection,
|
|
sortFolder,
|
|
getAllRequestsInFolderRecursively,
|
|
getEnvVars,
|
|
getFormattedCollectionOauth2Credentials
|
|
} |