ttsc
Version:
General-purpose TypeScript-Go compiler, runtime, plugin host, and LSP host.
83 lines • 3.16 kB
JavaScript
;
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