// Runs one CLI command for `bin/quak.ts` and exits with its code. import type { Writable } from "node:stream"; // Run a command and exit with its code once stdout/stderr have drained. // Exiting before the drain can truncate piped output, and the library can keep // the event loop alive after a command returns, so a plain return could hang. // An error the command throws is printed as one `quak: MESSAGE` line, without // the stack trace, and exits 1. export const run = async ( command: Promise, stdout: Writable, stderr: Writable, exit: (code: number) => void, ): Promise => { let code: number; try { code = await command; } catch (err) { stderr.write( `quak: ${err instanceof Error ? err.message : String(err)}\n`, ); code = 1; } const pending = [stdout, stderr].filter((s) => s.writableLength > 0); if (pending.length === 0) { exit(code); return; } let remaining = pending.length; for (const s of pending) { s.once("drain", () => { if (--remaining === 0) exit(code); }); } };