// hook-helper.mjs — Shared test helper for hook scripts. // Spawns a hook as a child process and feeds it JSON via stdin. import { execFile } from 'node:child_process'; /** * Run a hook script by spawning `node ` and piping `input` to stdin. * * @param {string} scriptPath - Absolute path to the hook .mjs file * @param {object|string} input - JSON payload (object will be stringified) * @returns {Promise<{ code: number, stdout: string, stderr: string }>} */ export function runHook(scriptPath, input) { return runHookWithEnv(scriptPath, input, {}); } /** * Run a hook script with custom environment variables. * * @param {string} scriptPath - Absolute path to the hook .mjs file * @param {object|string} input - JSON payload (object will be stringified) * @param {Record} envOverrides - Extra env vars to set * @returns {Promise<{ code: number, stdout: string, stderr: string }>} */ export function runHookWithEnv(scriptPath, input, envOverrides) { return new Promise((resolve) => { const env = { ...process.env, ...envOverrides }; const child = execFile( 'node', [scriptPath], { timeout: 5000, env }, (err, stdout, stderr) => { resolve({ code: child.exitCode ?? (err && err.code === 'ERR_CHILD_PROCESS_STDIO_FINAL' ? 0 : 1), stdout: stdout || '', stderr: stderr || '', }); } ); child.stdin.end(typeof input === 'string' ? input : JSON.stringify(input)); }); }