mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-29 07:34:07 +00:00
feat: enhance hook functionality with runSingleRequestByPathname
- Introduced runSingleRequestByPathname to allow running requests at the collection level. - Updated executeCollectionHooks to utilize the new function for improved hook execution. - Added comprehensive tests for bru.runRequest in various hook scenarios, ensuring correct behavior and response handling. - Removed redundant code and optimized hook management in collection.js.
This commit is contained in:
@@ -622,45 +622,7 @@ const handler = async function (argv) {
|
||||
console[type](...args);
|
||||
};
|
||||
|
||||
// Helper function to execute collection-level hooks at runtime
|
||||
const executeCollectionHooks = async (hookEvent, eventData) => {
|
||||
collectionRoot = collection?.draft?.root || collection?.root || {};
|
||||
const collectionHooks = get(collectionRoot, 'request.script.hooks', '');
|
||||
|
||||
if (!collectionHooks || !collectionHooks.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const hooksRuntime = new HooksRuntime({ runtime: scriptingConfig?.runtime });
|
||||
const result = await hooksRuntime.runHooks({
|
||||
hooksFile: decomment(collectionHooks),
|
||||
request: {}, // Placeholder request for collection-level hooks
|
||||
envVariables: envVars,
|
||||
runtimeVariables,
|
||||
collectionPath,
|
||||
onConsoleLog,
|
||||
processEnvVars,
|
||||
scriptingConfig,
|
||||
runRequestByItemPathname: null, // Not available at collection level
|
||||
collectionName
|
||||
});
|
||||
|
||||
if (result?.hookManager) {
|
||||
await result.hookManager.call(hookEvent, eventData);
|
||||
// Dispose HookManager to free VM resources
|
||||
if (result.hookManager && typeof result.hookManager.dispose === 'function') {
|
||||
result.hookManager.dispose();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error executing collection-level hooks for ${hookEvent}:`, error);
|
||||
}
|
||||
};
|
||||
|
||||
// Call onBeforeCollectionRun hook before starting to run requests
|
||||
await executeCollectionHooks(HOOK_EVENTS.RUNNER_BEFORE_COLLECTION_RUN, { collection });
|
||||
|
||||
// Define runSingleRequestByPathname before executeCollectionHooks so it's available at all hook levels
|
||||
const runSingleRequestByPathname = async (relativeItemPathname) => {
|
||||
const ext = FORMAT_CONFIG[collection.format].ext;
|
||||
return new Promise(async (resolve, reject) => {
|
||||
@@ -688,6 +650,45 @@ const handler = async function (argv) {
|
||||
});
|
||||
};
|
||||
|
||||
// Helper function to execute collection-level hooks at runtime
|
||||
const executeCollectionHooks = async (hookEvent, eventData) => {
|
||||
collectionRoot = collection?.draft?.root || collection?.root || {};
|
||||
const collectionHooks = get(collectionRoot, 'request.script.hooks', '');
|
||||
|
||||
if (!collectionHooks || !collectionHooks.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const hooksRuntime = new HooksRuntime({ runtime: scriptingConfig?.runtime });
|
||||
const result = await hooksRuntime.runHooks({
|
||||
hooksFile: decomment(collectionHooks),
|
||||
request: {}, // Placeholder request for collection-level hooks
|
||||
envVariables: envVars,
|
||||
runtimeVariables,
|
||||
collectionPath,
|
||||
onConsoleLog,
|
||||
processEnvVars,
|
||||
scriptingConfig,
|
||||
runRequestByItemPathname: runSingleRequestByPathname,
|
||||
collectionName
|
||||
});
|
||||
|
||||
if (result?.hookManager) {
|
||||
await result.hookManager.call(hookEvent, eventData);
|
||||
// Dispose HookManager to free VM resources
|
||||
if (result.hookManager && typeof result.hookManager.dispose === 'function') {
|
||||
result.hookManager.dispose();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error executing collection-level hooks for ${hookEvent}:`, error);
|
||||
}
|
||||
};
|
||||
|
||||
// Call onBeforeCollectionRun hook before starting to run requests
|
||||
await executeCollectionHooks(HOOK_EVENTS.RUNNER_BEFORE_COLLECTION_RUN, { collection });
|
||||
|
||||
let currentRequestIndex = 0;
|
||||
let nJumps = 0; // count the number of jumps to avoid infinite loops
|
||||
while (currentRequestIndex < requestItems.length) {
|
||||
|
||||
@@ -429,60 +429,6 @@ const HOOK_EVENTS = Object.freeze({
|
||||
RUNNER_AFTER_COLLECTION_RUN: 'runner:afterCollectionRun'
|
||||
});
|
||||
|
||||
/**
|
||||
* Get or create HookManager for a specific level (collection, folder, or request)
|
||||
* @param {Map} hookManagersMap - Map storing HookManagers by key
|
||||
* @param {string} key - Unique identifier (collection:${pathname}, folder:${pathname}, or request uid/pathname)
|
||||
* @param {string} hooksFile - Hooks file content for this level
|
||||
* @param {object} options - Options for hook registration
|
||||
* @param {object} options.request - Request object
|
||||
* @param {object} options.envVars - Environment variables (or envVariables)
|
||||
* @param {object} options.runtimeVariables - Runtime variables
|
||||
* @param {string} options.collectionPath - Collection path
|
||||
* @param {function} options.onConsoleLog - Console log callback
|
||||
* @param {object} options.processEnvVars - Process environment variables
|
||||
* @param {object} options.scriptingConfig - Scripting configuration
|
||||
* @param {function} options.runRequestByItemPathname - Function to run requests
|
||||
* @param {string} options.collectionName - Collection name
|
||||
* @returns {Promise<HookManager>} HookManager instance for this level
|
||||
*/
|
||||
const getOrCreateHookManager = async (hookManagersMap, key, hooksFile, options = {}) => {
|
||||
// Return existing HookManager if already created
|
||||
if (hookManagersMap.has(key)) {
|
||||
return hookManagersMap.get(key);
|
||||
}
|
||||
|
||||
// Create new HookManager and register hooks
|
||||
const hookManager = new HookManager();
|
||||
hookManagersMap.set(key, hookManager);
|
||||
|
||||
if (hooksFile && hooksFile.trim()) {
|
||||
const hooksRuntime = new HooksRuntime({ runtime: options.scriptingConfig?.runtime });
|
||||
try {
|
||||
await hooksRuntime.runHooks({
|
||||
hooksFile: decomment(hooksFile),
|
||||
hookManager,
|
||||
request: options.request || {},
|
||||
envVariables: options.envVars || options.envVariables || {},
|
||||
runtimeVariables: options.runtimeVariables || {},
|
||||
collectionPath: options.collectionPath,
|
||||
onConsoleLog: options.onConsoleLog,
|
||||
processEnvVars: options.processEnvVars || {},
|
||||
scriptingConfig: options.scriptingConfig || {},
|
||||
runRequestByItemPathname: options.runRequestByItemPathname,
|
||||
collectionName: options.collectionName
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error registering hooks for ${key}:`, error);
|
||||
if (options.onConsoleLog) {
|
||||
options.onConsoleLog('error', [`Error registering hooks for ${key}: ${error.message}`]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hookManager;
|
||||
};
|
||||
|
||||
const getAllRequestsInFolder = (folderItems = [], recursive = true) => {
|
||||
let requests = [];
|
||||
|
||||
@@ -714,6 +660,5 @@ module.exports = {
|
||||
getAllRequestsAtFolderRoot,
|
||||
getCallStack,
|
||||
extractHooks,
|
||||
HOOK_EVENTS,
|
||||
getOrCreateHookManager
|
||||
HOOK_EVENTS
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user