UNPKG

@sentzunhat/zacatl

Version:

A modular, high-performance TypeScript microservice framework for Node.js, featuring layered architecture, dependency injection, and robust validation for building scalable APIs and distributed systems.

82 lines 2.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runCommand = void 0; const child_process_1 = require("child_process"); const policy_1 = require("./policy"); const types_1 = require("./types"); const SIGKILL_GRACE_MS = 2_000; const runCommand = (spec, policy) => { return new Promise((resolve, reject) => { const parsed = types_1.commandSpecSchema.safeParse(spec); if (!parsed.success) { reject(parsed.error); return; } try { (0, policy_1.validateCommandSpec)(parsed.data, policy); } catch (err) { reject(err); return; } const startMs = Date.now(); let stdout = ''; let stderr = ''; let timedOut = false; let outputBytes = 0; const env = policy.inheritEnv ? { ...process.env, ...(parsed.data.env ?? {}) } : { ...(parsed.data.env ?? {}) }; const child = (0, child_process_1.spawn)(parsed.data.cmd, parsed.data.args, { shell: false, cwd: parsed.data.cwd, env, stdio: ['ignore', 'pipe', 'pipe'], }); const killTimer = setTimeout(() => { timedOut = true; child.kill('SIGTERM'); const forceKill = setTimeout(() => child.kill('SIGKILL'), SIGKILL_GRACE_MS); if (typeof forceKill.unref === 'function') forceKill.unref(); }, policy.timeoutMs); child.stdout.on('data', (chunk) => { outputBytes += chunk.byteLength; if (outputBytes <= policy.maxOutputBytes) { stdout += chunk.toString('utf-8'); } }); child.stderr.on('data', (chunk) => { outputBytes += chunk.byteLength; if (outputBytes <= policy.maxOutputBytes) { stderr += chunk.toString('utf-8'); } }); child.on('close', (code) => { clearTimeout(killTimer); resolve({ cmd: parsed.data.cmd, args: parsed.data.args, exitCode: code, stdout, stderr, timedOut, durationMs: Date.now() - startMs, }); }); child.on('error', (err) => { clearTimeout(killTimer); resolve({ cmd: parsed.data.cmd, args: parsed.data.args, exitCode: null, stdout, stderr: stderr ? `${stderr}\n${err.message}` : err.message, timedOut, durationMs: Date.now() - startMs, }); }); }); }; exports.runCommand = runCommand; //# sourceMappingURL=runner.js.map