UNPKG

@usebruno/cli

Version:

With Bruno CLI, you can now run your API collections with ease using simple command line commands.

95 lines (82 loc) 3.7 kB
const chalk = require('chalk'); const constants = require('../constants'); const { GITHUB_DISCUSSION_URL, scriptWritesEnvVar } = require('@usebruno/common/utils'); const collectScriptsFromRequest = (request) => { if (!request) return []; return [request.script?.req, request.script?.res, request.tests]; }; /** * Walks the folder tree and collects scripts only from folders that contain at least one * request in `runningPaths` — i.e. folders whose scripts will actually execute this run. * Returns whether the visited subtree contains a running request so parents can include * their own scripts. A single post-order pass, so each node is visited once. */ const collectRunningFolderScripts = (items = [], runningPaths, out) => { let subtreeHasRunningRequest = false; for (const item of items) { if (item?.type === 'folder') { const childScripts = []; const folderHasRunningRequest = collectRunningFolderScripts(item.items || [], runningPaths, childScripts); if (folderHasRunningRequest) { const folderRoot = item?.draft || item?.root; out.push(...collectScriptsFromRequest(folderRoot?.request)); out.push(...childScripts); subtreeHasRunningRequest = true; } } else if (runningPaths.has(item?.pathname)) { subtreeHasRunningRequest = true; } } return subtreeHasRunningRequest; }; /** * Detects whether any script that will actually run this invocation calls an env-var write * API without the `{ persist: false }` opt-out. Only scripts that execute are considered: * request-level scripts for the requests in the run set, the collection-level script (which * runs for every executed request), and folder-level scripts for folders that contain a * request in the run set. Scripts that never run (filtered-out requests/folders, or an empty * run set) are not scanned. */ const detectEnvVarWriteUsage = (requestItems = [], collectionRoot = {}, collection = null) => { if (!requestItems.length) return false; const scripts = []; // Collection-level scripts run for every executed request, and at least one request runs. scripts.push(...collectScriptsFromRequest(collectionRoot?.request)); // Request-level scripts for the requests in the run set. for (const item of requestItems) { scripts.push(...collectScriptsFromRequest(item?.request)); } // Folder-level scripts, but only for folders an executed request lives under. if (collection?.items) { const runningPaths = new Set(requestItems.map((item) => item?.pathname).filter(Boolean)); collectRunningFolderScripts(collection.items, runningPaths, scripts); } return scripts.some((code) => scriptWritesEnvVar(code)); }; const printEnvVarWriteWarning = () => { const yellow = chalk.hex(constants.COLORS.ORANGE); console.log(); console.log(yellow.bold('⚠️ Heads up: Bruno v4 migration')); console.log( chalk.white( 'In v4 (to be released in 3rd week of July), script APIs: bru.setEnvVar(), bru.setGlobalEnvVar(), that set environment variables will write to the disk. If you are using it to set secrets, it could be committed to Git.' ) ); console.log( chalk.white('Migrate to bru.setVar() before v4 to keep values runtime-only. Please ignore if already done.') + ' ' + chalk.white('Read more: ' + GITHUB_DISCUSSION_URL) ); console.log(); }; const maybePrintEnvVarWriteWarning = (requestItems, collectionRoot, collection) => { if (detectEnvVarWriteUsage(requestItems, collectionRoot, collection)) { printEnvVarWriteWarning(); } }; module.exports = { scriptWritesEnvVar, detectEnvVarWriteUsage, printEnvVarWriteWarning, maybePrintEnvVarWriteWarning };