import * as plugins from './tstest.plugins.js'; import type { TsTestLogger } from './tstest.logging.js'; import type { Smartshell } from '@push.rocks/smartshell'; export interface IBeforeScripts { /** The "test:before" or "test:before:once" script command, or null if not defined */ beforeOnce: string | null; /** The "test:before:testfile" script command, or null if not defined */ beforeTestfile: string | null; } /** * Load before-script commands from the project's package.json scripts section. */ export function loadBeforeScripts(cwd: string): IBeforeScripts { const result: IBeforeScripts = { beforeOnce: null, beforeTestfile: null }; try { const packageJsonPath = plugins.path.join(cwd, 'package.json'); const packageJson = JSON.parse(plugins.fs.readFileSync(packageJsonPath, 'utf8')); const scripts = packageJson?.scripts; if (!scripts) return result; // test:before takes precedence over test:before:once (they are aliases) if (scripts['test:before']) { result.beforeOnce = scripts['test:before']; if (scripts['test:before:once']) { console.warn('Warning: Both "test:before" and "test:before:once" are defined. Using "test:before".'); } } else if (scripts['test:before:once']) { result.beforeOnce = scripts['test:before:once']; } if (scripts['test:before:testfile']) { result.beforeTestfile = scripts['test:before:testfile']; } } catch { // No package.json or parse error — return defaults } return result; } /** * Execute a before-script command and return whether it succeeded. */ export async function runBeforeScript( smartshellInstance: Smartshell, command: string, label: string, logger: TsTestLogger, env?: { TSTEST_FILE?: string; TSTEST_RUNTIME?: string }, ): Promise { logger.beforeScriptStart(label, command); const startTime = Date.now(); // Set environment variables if provided const envKeysSet: string[] = []; if (env) { for (const [key, value] of Object.entries(env)) { if (value !== undefined) { process.env[key] = value; envKeysSet.push(key); } } } try { const execResult = await smartshellInstance.execStreaming(command); const result = await execResult.finalPromise; const durationMs = Date.now() - startTime; const success = result.exitCode === 0; logger.beforeScriptEnd(label, success, durationMs); return success; } catch { const durationMs = Date.now() - startTime; logger.beforeScriptEnd(label, false, durationMs); return false; } finally { // Clean up environment variables for (const key of envKeysSet) { delete process.env[key]; } } }