"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.__tsfTypeAliases = void 0;
exports.execProcess = execProcess;
const tslib_1 = require("tslib");
const _a = tslib_1.__importStar(require("@zyno-io/ts-reflection/type-metadata-runtime"));
const node_child_process_1 = require("node:child_process");
const error_1 = require("../utils/error");
async function execProcess(cmd, args = [], options = {}) {
    try {
        return await new Promise((resolve, reject) => {
            const stdout = [];
            const stderr = [];
            const proc = (0, node_child_process_1.spawn)(cmd, [...args], {
                cwd: options.cwd,
                stdio: options.stdio,
                shell: options.shell,
                env: options.env
            });
            let settled = false;
            const settle = (callback) => {
                if (settled)
                    return;
                settled = true;
                callback();
            };
            proc.on('error', error => settle(() => reject(error)));
            proc.on('spawn', () => {
                try {
                    options.onSpawn?.(proc);
                }
                catch (error) {
                    if (!proc.killed)
                        proc.kill();
                    settle(() => reject(error));
                }
            });
            proc.stdout?.on('data', data => stdout.push(Buffer.from(data)));
            proc.stderr?.on('data', data => stderr.push(Buffer.from(data)));
            proc.on('close', code => {
                settle(() => {
                    const result = {
                        code,
                        stdout: Buffer.concat(stdout),
                        stderr: Buffer.concat(stderr)
                    };
                    if (options.errorOnNonZero !== false && code !== 0) {
                        reject(Object.assign(new Error(`Process exited with code ${code}`), { result }));
                        return;
                    }
                    resolve(result);
                });
            });
        });
    }
    catch (error) {
        throw (0, error_1.toError)(`Failure during execution of process with command: ${formatCommand(cmd, args)}`, error);
    }
}
function formatCommand(cmd, args) {
    return [cmd, ...args.map(arg => (arg.includes(' ') ? `"${arg}"` : arg))].join(' ');
}
exports.__tsfTypeAliases = _a.decodeCompactMetadataV1("[1,{\"ExecProcessOptions\":{\"kind\":18,\"typeName\":\"ExecProcessOptions\",\"types\":[{\"kind\":20,\"name\":\"cwd\",\"type\":{\"kind\":12,\"types\":[{\"kind\":6},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"errorOnNonZero\",\"type\":{\"kind\":12,\"types\":[{\"kind\":8},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"stdio\",\"type\":{\"kind\":12,\"types\":[{\"kind\":2,\"typeName\":\"SpawnOptions['stdio']\"},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"onSpawn\",\"type\":{\"kind\":12,\"types\":[{\"kind\":2,\"typeName\":\"(proc: ChildProcess) =\\u003e void\"},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"shell\",\"type\":{\"kind\":12,\"types\":[{\"kind\":8},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"env\",\"type\":{\"kind\":12,\"types\":[{\"kind\":16,\"typeName\":\"NodeJS.ProcessEnv\",\"classType\":{\"$tsf\":0}},{\"kind\":4}]},\"optional\":true}]},\"ExecProcessResult\":{\"kind\":18,\"typeName\":\"ExecProcessResult\",\"types\":[{\"kind\":20,\"name\":\"code\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":5}]},\"optional\":false},{\"kind\":20,\"name\":\"stdout\",\"type\":{\"kind\":16,\"typeName\":\"Buffer\",\"classType\":{\"$tsf\":1}},\"optional\":false},{\"kind\":20,\"name\":\"stderr\",\"type\":{\"kind\":16,\"typeName\":\"Buffer\",\"classType\":{\"$tsf\":1}},\"optional\":false}]}}]", [() => NodeJS.ProcessEnv, () => (typeof Buffer !== "undefined" ? Buffer : (typeof exports !== "undefined" ? exports.Buffer : undefined))]);
//# sourceMappingURL=process.js.map