UNPKG

ttsc

Version:

General-purpose TypeScript-Go compiler, runtime, plugin host, and LSP host.

83 lines 3.16 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.spawnNative = spawnNative; exports.ensureExecutable = ensureExecutable; exports.outputText = outputText; const node_child_process_1 = require("node:child_process"); const node_fs_1 = __importDefault(require("node:fs")); const captureProcessOutput_1 = require("./captureProcessOutput"); /** * Spawn a native binary (or a Node.js script when the path has a JS/TS * extension) and return its result with `stdout` and `stderr` as text. * * The child's streams are written to files rather than piped, and the files are * read once it exits. `spawnSync` buffers a _piped_ stream in this process's * memory and refuses to hold more than `maxBuffer` bytes, so a piped capture * has to name a ceiling — and any ceiling is a number nobody chose for this * machine, deciding that a large but legitimate compile said too much. A file * has no such limit: the bytes never pass through this heap on their way out of * the child, and how many there may be is the filesystem's business. * * When `options.encoding` is omitted it defaults to `"utf8"`. Pass `"buffer"` * when the caller needs raw bytes. */ function spawnNative(binary, args, options) { const viaNode = /\.(?:[cm]?js|ts)$/i.test(binary); if (!viaNode) { ensureExecutable(binary); } const capture = (0, captureProcessOutput_1.captureProcessOutput)(); try { const result = (0, node_child_process_1.spawnSync)(viaNode ? process.execPath : binary, viaNode ? [binary, ...args] : [...args], { cwd: options.cwd, env: options.env, stdio: ["ignore", capture.stdoutFd, capture.stderrFd], windowsHide: true, }); const stdout = capture.read("stdout", options.encoding); const stderr = capture.read("stderr", options.encoding); return { ...result, output: [null, stdout, stderr], stderr, stdout, }; } finally { capture.dispose(); } } /** * Ensure the binary has the executable bit set on POSIX systems. Silently skips * on Windows and swallows `chmod` errors to let the original spawn error * surface instead of masking it with a permission error. */ function ensureExecutable(binary) { if (process.platform === "win32") { return; } try { node_fs_1.default.accessSync(binary, node_fs_1.default.constants.X_OK); return; } catch { try { const mode = node_fs_1.default.statSync(binary).mode & 0o777; node_fs_1.default.chmodSync(binary, mode | 0o755); } catch { /* keep the original spawn error path */ } } } /** Coerce a `spawnSync` output value to a plain string, defaulting to `""`. */ function outputText(value) { if (value == null) { return ""; } return typeof value === "string" ? value : value.toString("utf8"); } //# sourceMappingURL=spawnNative.js.map