UNPKG

@karinjs/node-pty

Version:

Fork pseudoterminals in Node.JS

903 lines (891 loc) 26.8 kB
import { __esm, __export, __require, __toCommonJS } from "./chunk-DA5uXrvU.js"; import { ConoutWorkerMessage, getWorkerPipeName, init_conout } from "./conout-DQRErfxK.js"; import path from "node:path"; import { fileURLToPath } from "node:url"; import * as fs from "fs"; import * as os from "os"; import * as path$1 from "path"; import { join } from "path"; import { EventEmitter } from "events"; import { fork as fork$1 } from "child_process"; import { Socket } from "net"; import { Worker } from "worker_threads"; import * as tty from "tty"; //#region node_modules/.pnpm/tsdown@0.14.1_typescript@5.9.2/node_modules/tsdown/esm-shims.js var getFilename, getDirname, __dirname; var init_esm_shims = __esm({ "node_modules/.pnpm/tsdown@0.14.1_typescript@5.9.2/node_modules/tsdown/esm-shims.js": (() => { getFilename = () => fileURLToPath(import.meta.url); getDirname = () => path.dirname(getFilename()); __dirname = /* @__PURE__ */ getDirname(); }) }); //#endregion //#region src/prebuild-file-path.ts function prebuildName() { const tags = []; tags.push(process.versions.hasOwnProperty("electron") ? "electron" : "node"); tags.push("abi" + process.versions.modules); if (os.platform() === "linux" && fs.existsSync("/etc/alpine-release")) tags.push("musl"); return tags.join(".") + ".node"; } var pathToBuild, ptyPath; var init_prebuild_file_path = __esm({ "src/prebuild-file-path.ts": (() => { init_esm_shims(); pathToBuild = path$1.resolve(__dirname, `../prebuilds/${os.platform()}-${os.arch()}/${prebuildName()}`); ptyPath = fs.existsSync(pathToBuild) ? pathToBuild : null; }) }); //#endregion //#region src/eventEmitter2.ts var EventEmitter2; var init_eventEmitter2 = __esm({ "src/eventEmitter2.ts": (() => { EventEmitter2 = class { _listeners = []; _event; get event() { if (!this._event) this._event = (listener) => { this._listeners.push(listener); const disposable = { dispose: () => { for (let i = 0; i < this._listeners.length; i++) if (this._listeners[i] === listener) { this._listeners.splice(i, 1); return; } } }; return disposable; }; return this._event; } fire(data) { const queue = []; for (let i = 0; i < this._listeners.length; i++) queue.push(this._listeners[i]); for (let i = 0; i < queue.length; i++) queue[i].call(void 0, data); } }; }) }); //#endregion //#region src/terminal.ts var DEFAULT_COLS, DEFAULT_ROWS, FLOW_CONTROL_PAUSE, FLOW_CONTROL_RESUME, Terminal; var init_terminal = __esm({ "src/terminal.ts": (() => { init_eventEmitter2(); DEFAULT_COLS = 80; DEFAULT_ROWS = 24; FLOW_CONTROL_PAUSE = ""; FLOW_CONTROL_RESUME = ""; Terminal = class { _socket; _pid = 0; _fd = 0; _pty; _file; _name; _cols = 0; _rows = 0; _readable = false; _writable = false; _internalee; _flowControlPause; _flowControlResume; handleFlowControl; _onData = new EventEmitter2(); get onData() { return this._onData.event; } _onExit = new EventEmitter2(); get onExit() { return this._onExit.event; } get pid() { return this._pid; } get cols() { return this._cols; } get rows() { return this._rows; } constructor(opt) { this._internalee = new EventEmitter(); this.handleFlowControl = !!opt?.handleFlowControl; this._flowControlPause = opt?.flowControlPause || FLOW_CONTROL_PAUSE; this._flowControlResume = opt?.flowControlResume || FLOW_CONTROL_RESUME; if (!opt) return; this._checkType("name", opt.name ? opt.name : void 0, "string"); this._checkType("cols", opt.cols ? opt.cols : void 0, "number"); this._checkType("rows", opt.rows ? opt.rows : void 0, "number"); this._checkType("cwd", opt.cwd ? opt.cwd : void 0, "string"); this._checkType("env", opt.env ? opt.env : void 0, "object"); this._checkType("uid", opt.uid ? opt.uid : void 0, "number"); this._checkType("gid", opt.gid ? opt.gid : void 0, "number"); this._checkType("encoding", opt.encoding ? opt.encoding : void 0, "string"); } write(data) { if (this.handleFlowControl) { if (data === this._flowControlPause) { this.pause(); return; } if (data === this._flowControlResume) { this.resume(); return; } } this._write(data); } _forwardEvents() { this.on("data", (e) => this._onData.fire(e)); this.on("exit", (exitCode, signal) => this._onExit.fire({ exitCode, signal })); } _checkType(name, value, type, allowArray = false) { if (value === void 0) return; if (allowArray) { if (Array.isArray(value)) { value.forEach((v, i) => { if (typeof v !== type) throw new Error(`${name}[${i}] must be a ${type} (not a ${typeof v[i]})`); }); return; } } if (typeof value !== type) throw new Error(`${name} must be a ${type} (not a ${typeof value})`); } /** See net.Socket.end */ end(data) { this._socket.end(data); } /** See stream.Readable.pipe */ pipe(dest, options) { return this._socket.pipe(dest, options); } /** See net.Socket.pause */ pause() { return this._socket.pause(); } /** See net.Socket.resume */ resume() { return this._socket.resume(); } /** See net.Socket.setEncoding */ setEncoding(encoding) { if (this._socket._decoder) delete this._socket._decoder; if (encoding) this._socket.setEncoding(encoding); } addListener(eventName, listener) { this.on(eventName, listener); } on(eventName, listener) { if (eventName === "close") { this._internalee.on("close", listener); return; } this._socket.on(eventName, listener); } emit(eventName, ...args) { if (eventName === "close") return this._internalee.emit.apply(this._internalee, arguments); return this._socket.emit.apply(this._socket, arguments); } listeners(eventName) { return this._socket.listeners(eventName); } removeListener(eventName, listener) { this._socket.removeListener(eventName, listener); } removeAllListeners(eventName) { this._socket.removeAllListeners(eventName); } once(eventName, listener) { this._socket.once(eventName, listener); } _close() { this._socket.readable = false; this.write = () => {}; this.end = () => {}; this._writable = false; this._readable = false; } _parseEnv(env) { const keys = Object.keys(env || {}); const pairs = []; for (let i = 0; i < keys.length; i++) { if (keys[i] === void 0) continue; pairs.push(keys[i] + "=" + env[keys[i]]); } return pairs; } }; }) }); //#endregion //#region src/windowsConoutConnection.ts var FLUSH_DATA_INTERVAL$1, ConoutConnection; var init_windowsConoutConnection = __esm({ "src/windowsConoutConnection.ts": (() => { init_esm_shims(); init_conout(); init_eventEmitter2(); FLUSH_DATA_INTERVAL$1 = 1e3; ConoutConnection = class { _worker; _drainTimeout; _isDisposed = false; _onReady = new EventEmitter2(); get onReady() { return this._onReady.event; } constructor(_conoutPipeName, _useConptyDll) { this._conoutPipeName = _conoutPipeName; this._useConptyDll = _useConptyDll; const workerData$1 = { conoutPipeName: _conoutPipeName }; const scriptPath = __dirname.replace("node_modules.asar", "node_modules.asar.unpacked"); this._worker = new Worker(join(scriptPath, "worker/conoutSocketWorker.js"), { workerData: workerData$1 }); this._worker.on("message", (message) => { switch (message) { case ConoutWorkerMessage.READY: this._onReady.fire(); return; default: console.warn("Unexpected ConoutWorkerMessage", message); } }); } dispose() { if (!this._useConptyDll && this._isDisposed) return; this._isDisposed = true; this._drainDataAndClose(); } connectSocket(socket) { socket.connect(getWorkerPipeName(this._conoutPipeName)); } _drainDataAndClose() { if (this._drainTimeout) clearTimeout(this._drainTimeout); this._drainTimeout = setTimeout(() => this._destroySocket(), FLUSH_DATA_INTERVAL$1); } async _destroySocket() { await this._worker.terminate(); } }; }) }); //#endregion //#region src/windowsPtyAgent.ts function argsToCommandLine(file, args) { if (isCommandLine(args)) { if (args.length === 0) return file; return `${argsToCommandLine(file, [])} ${args}`; } const argv = [file]; Array.prototype.push.apply(argv, args); let result = ""; for (let argIndex = 0; argIndex < argv.length; argIndex++) { if (argIndex > 0) result += " "; const arg = argv[argIndex]; const hasLopsidedEnclosingQuote = xOr(arg[0] !== "\"", arg[arg.length - 1] !== "\""); const hasNoEnclosingQuotes = arg[0] !== "\"" && arg[arg.length - 1] !== "\""; const quote = arg === "" || (arg.indexOf(" ") !== -1 || arg.indexOf(" ") !== -1) && arg.length > 1 && (hasLopsidedEnclosingQuote || hasNoEnclosingQuotes); if (quote) result += "\""; let bsCount = 0; for (let i = 0; i < arg.length; i++) { const p = arg[i]; if (p === "\\") bsCount++; else if (p === "\"") { result += repeatText("\\", bsCount * 2 + 1); result += "\""; bsCount = 0; } else { result += repeatText("\\", bsCount); bsCount = 0; result += p; } } if (quote) { result += repeatText("\\", bsCount * 2); result += "\""; } else result += repeatText("\\", bsCount); } return result; } function isCommandLine(args) { return typeof args === "string"; } function repeatText(text, count) { let result = ""; for (let i = 0; i < count; i++) result += text; return result; } function xOr(arg1, arg2) { return arg1 && !arg2 || !arg1 && arg2; } var conptyNative, winptyNative, FLUSH_DATA_INTERVAL, WindowsPtyAgent; var init_windowsPtyAgent = __esm({ "src/windowsPtyAgent.ts": (() => { init_esm_shims(); init_windowsConoutConnection(); ; ; FLUSH_DATA_INTERVAL = 1e3; WindowsPtyAgent = class { _inSocket; _outSocket; _pid = 0; _innerPid = 0; _closeTimeout; _exitCode; _conoutSocketWorker; _fd; _pty; _ptyNative; get inSocket() { return this._inSocket; } get outSocket() { return this._outSocket; } get fd() { return this._fd; } get innerPid() { return this._innerPid; } get pty() { return this._pty; } constructor(file, args, env, cwd, cols, rows, debug, _useConpty, _useConptyDll = false, conptyInheritCursor = false) { this._useConpty = _useConpty; this._useConptyDll = _useConptyDll; if (this._useConpty === void 0 || this._useConpty === true) this._useConpty = this._getWindowsBuildNumber() >= 18309; if (this._useConpty) { if (!conptyNative) try { conptyNative = __require("../build/Release/conpty.node"); } catch (outerError) { try { conptyNative = __require("../build/Debug/conpty.node"); } catch (innerError) { console.error("innerError", innerError); throw outerError; } } } else if (!winptyNative) try { winptyNative = __require("../build/Release/pty.node"); } catch (outerError) { try { winptyNative = __require("../build/Debug/pty.node"); } catch (innerError) { console.error("innerError", innerError); throw outerError; } } this._ptyNative = this._useConpty ? conptyNative : winptyNative; cwd = path$1.resolve(cwd); const commandLine = argsToCommandLine(file, args); let term; if (this._useConpty) term = this._ptyNative.startProcess(file, cols, rows, debug, this._generatePipeName(), conptyInheritCursor, this._useConptyDll); else { term = this._ptyNative.startProcess(file, commandLine, env, cwd, cols, rows, debug); this._pid = term.pid; this._innerPid = term.innerPid; } this._fd = term.fd; this._pty = term.pty; this._outSocket = new Socket(); this._outSocket.setEncoding("utf8"); this._conoutSocketWorker = new ConoutConnection(term.conout, this._useConptyDll); this._conoutSocketWorker.onReady(() => { this._conoutSocketWorker.connectSocket(this._outSocket); }); this._outSocket.on("connect", () => { this._outSocket.emit("ready_datapipe"); }); const inSocketFD = fs.openSync(term.conin, "w"); this._inSocket = new Socket({ fd: inSocketFD, readable: false, writable: true }); this._inSocket.setEncoding("utf8"); if (this._useConpty) { const connect = this._ptyNative.connect(this._pty, commandLine, cwd, env, this._useConptyDll, (c) => this._$onProcessExit(c)); this._innerPid = connect.pid; } } resize(cols, rows) { if (this._useConpty) { if (this._exitCode !== void 0) throw new Error("Cannot resize a pty that has already exited"); this._ptyNative.resize(this._pty, cols, rows, this._useConptyDll); return; } this._ptyNative.resize(this._pid, cols, rows); } clear() { if (this._useConpty) this._ptyNative.clear(this._pty, this._useConptyDll); } kill() { if (this._useConpty) if (!this._useConptyDll) { this._inSocket.readable = false; this._outSocket.readable = false; this._getConsoleProcessList().then((consoleProcessList) => { consoleProcessList.forEach((pid) => { try { process.kill(pid); } catch (e) {} }); }); this._ptyNative.kill(this._pty, this._useConptyDll); this._conoutSocketWorker.dispose(); } else { this._inSocket.destroy(); this._ptyNative.kill(this._pty, this._useConptyDll); this._outSocket.on("data", () => { this._conoutSocketWorker.dispose(); }); } else { const processList = this._ptyNative.getProcessList(this._pid); this._ptyNative.kill(this._pid, this._innerPid); processList.forEach((pid) => { try { process.kill(pid); } catch (e) {} }); } } _getConsoleProcessList() { return new Promise((resolve) => { const agent = fork$1(path$1.join(__dirname, "conpty_console_list_agent"), [this._innerPid.toString()]); agent.on("message", (message) => { clearTimeout(timeout); resolve(message.consoleProcessList); }); const timeout = setTimeout(() => { agent.kill(); resolve([this._innerPid]); }, 5e3); }); } get exitCode() { if (this._useConpty) return this._exitCode; const winptyExitCode = this._ptyNative.getExitCode(this._innerPid); return winptyExitCode === -1 ? void 0 : winptyExitCode; } _getWindowsBuildNumber() { const osVersion = /(\d+)\.(\d+)\.(\d+)/g.exec(os.release()); let buildNumber = 0; if (osVersion && osVersion.length === 4) buildNumber = parseInt(osVersion[3]); return buildNumber; } _generatePipeName() { return `conpty-${Math.random() * 1e7}`; } /** * Triggered from the native side when a contpy process exits. */ _$onProcessExit(exitCode) { this._exitCode = exitCode; if (!this._useConptyDll) { this._flushDataAndCleanUp(); this._outSocket.on("data", () => this._flushDataAndCleanUp()); } } _flushDataAndCleanUp() { if (this._useConptyDll) return; if (this._closeTimeout) clearTimeout(this._closeTimeout); this._closeTimeout = setTimeout(() => this._cleanUpProcess(), FLUSH_DATA_INTERVAL); } _cleanUpProcess() { if (this._useConptyDll) return; this._inSocket.readable = false; this._outSocket.readable = false; this._outSocket.destroy(); } }; }) }); //#endregion //#region src/utils.ts /** * Copyright (c) 2017, Daniel Imms (MIT License). * Copyright (c) 2018, Microsoft Corporation (MIT License). */ function assign(target, ...sources) { sources.forEach((source) => Object.keys(source).forEach((key) => target[key] = source[key])); return target; } var init_utils = __esm({ "src/utils.ts": (() => {}) }); //#endregion //#region src/windowsTerminal.ts var windowsTerminal_exports = {}; __export(windowsTerminal_exports, { WindowsTerminal: () => WindowsTerminal }); var DEFAULT_FILE$1, DEFAULT_NAME$1, WindowsTerminal; var init_windowsTerminal = __esm({ "src/windowsTerminal.ts": (() => { init_terminal(); init_windowsPtyAgent(); init_utils(); DEFAULT_FILE$1 = "cmd.exe"; DEFAULT_NAME$1 = "Windows Shell"; WindowsTerminal = class extends Terminal { _isReady; _deferreds; _agent; constructor(file, args, opt) { super(opt); this._checkType("args", args, "string", true); args = args || []; file = file || DEFAULT_FILE$1; opt = opt || {}; opt.env = opt.env || process.env; if (opt.encoding) console.warn("Setting encoding on Windows is not supported"); const env = assign({}, opt.env); this._cols = opt.cols || DEFAULT_COLS; this._rows = opt.rows || DEFAULT_ROWS; const cwd = opt.cwd || process.cwd(); const name = opt.name || env.TERM || DEFAULT_NAME$1; const parsedEnv = this._parseEnv(env); this._isReady = false; this._deferreds = []; this._agent = new WindowsPtyAgent(file, args, parsedEnv, cwd, this._cols, this._rows, false, opt.useConpty, opt.useConptyDll, opt.conptyInheritCursor); this._socket = this._agent.outSocket; this._pid = this._agent.innerPid; this._fd = this._agent.fd; this._pty = this._agent.pty; this._socket.on("ready_datapipe", () => { [ "connect", "data", "end", "timeout", "drain" ].forEach((event) => { this._socket.on(event, () => { if (!this._isReady && event === "data") { this._isReady = true; this._deferreds.forEach((fn) => { fn.run(); }); this._deferreds = []; } }); }); this._socket.on("error", (err) => { this._close(); if (err.code) { if (~err.code.indexOf("errno 5") || ~err.code.indexOf("EIO")) return; } if (this.listeners("error").length < 2) throw err; }); this._socket.on("close", () => { this.emit("exit", this._agent.exitCode); this._close(); }); }); this._file = file; this._name = name; this._readable = true; this._writable = true; this._forwardEvents(); } _write(data) { this._defer(this._doWrite, data); } _doWrite(data) { this._agent.inSocket.write(data); } /** * openpty */ static open(options) { throw new Error("open() not supported on windows, use Fork() instead."); } /** * TTY */ resize(cols, rows) { if (cols <= 0 || rows <= 0 || isNaN(cols) || isNaN(rows) || cols === Infinity || rows === Infinity) throw new Error("resizing must be done using positive cols and rows"); this._deferNoArgs(() => { this._agent.resize(cols, rows); this._cols = cols; this._rows = rows; }); } clear() { this._deferNoArgs(() => { this._agent.clear(); }); } destroy() { this._deferNoArgs(() => { this.kill(); }); } kill(signal) { this._deferNoArgs(() => { if (signal) throw new Error("Signals not supported on windows."); this._close(); this._agent.kill(); }); } _deferNoArgs(deferredFn) { if (this._isReady) { deferredFn.call(this); return; } this._deferreds.push({ run: () => deferredFn.call(this) }); } _defer(deferredFn, arg) { if (this._isReady) { deferredFn.call(this, arg); return; } this._deferreds.push({ run: () => deferredFn.call(this, arg) }); } get process() { return this._name; } get master() { throw new Error("master is not supported on Windows"); } get slave() { throw new Error("slave is not supported on Windows"); } }; }) }); //#endregion //#region src/prebuild-loader.ts var pty$1, pty; var init_prebuild_loader = __esm({ "src/prebuild-loader.ts": (() => { init_prebuild_file_path(); ; try { pty$1 = __require(ptyPath || "../build/Release/pty.node"); } catch (outerError) { try { pty$1 = ptyPath ? __require("../build/Release/pty.node") : __require("../build/Debug/pty.node"); } catch (innerError) { console.error("innerError", innerError); throw outerError; } } pty = pty$1; }) }); //#endregion //#region src/unixTerminal.ts var unixTerminal_exports = {}; __export(unixTerminal_exports, { UnixTerminal: () => UnixTerminal }); var helperPath, DEFAULT_FILE, DEFAULT_NAME, DESTROY_SOCKET_TIMEOUT_MS, UnixTerminal; var init_unixTerminal = __esm({ "src/unixTerminal.ts": (() => { init_esm_shims(); init_terminal(); init_utils(); init_prebuild_loader(); ; helperPath = "../build/Release/spawn-helper"; helperPath = path$1.resolve(__dirname, helperPath); helperPath = helperPath.replace("app.asar", "app.asar.unpacked"); helperPath = helperPath.replace("node_modules.asar", "node_modules.asar.unpacked"); DEFAULT_FILE = "sh"; DEFAULT_NAME = "xterm"; DESTROY_SOCKET_TIMEOUT_MS = 200; UnixTerminal = class UnixTerminal extends Terminal { _fd; _pty; _file; _name; _readable; _writable; _boundClose = false; _emittedClose = false; _master; _slave; get master() { return this._master; } get slave() { return this._slave; } constructor(file, args, opt) { super(opt); if (typeof args === "string") throw new Error("args as a string is not supported on unix."); args = args || []; file = file || DEFAULT_FILE; opt = opt || {}; opt.env = opt.env || process.env; this._cols = opt.cols || DEFAULT_COLS; this._rows = opt.rows || DEFAULT_ROWS; const uid = opt.uid ?? -1; const gid = opt.gid ?? -1; const env = assign({}, opt.env); if (opt.env === process.env) this._sanitizeEnv(env); const cwd = opt.cwd || process.cwd(); env.PWD = cwd; const name = opt.name || env.TERM || DEFAULT_NAME; env.TERM = name; const parsedEnv = this._parseEnv(env); const encoding = opt.encoding === void 0 ? "utf8" : opt.encoding; const onexit = (code, signal) => { if (!this._emittedClose) { if (this._boundClose) return; this._boundClose = true; let timeout = setTimeout(() => { timeout = null; this._socket.destroy(); }, DESTROY_SOCKET_TIMEOUT_MS); this.once("close", () => { if (timeout !== null) clearTimeout(timeout); this.emit("exit", code, signal); }); return; } this.emit("exit", code, signal); }; const term = pty.fork(file, args, parsedEnv, cwd, this._cols, this._rows, uid, gid, encoding === "utf8", helperPath, onexit); this._socket = new tty.ReadStream(term.fd); if (encoding !== null) this._socket.setEncoding(encoding); this._socket.on("error", (err) => { if (err.code) { if (~err.code.indexOf("EAGAIN")) return; } this._close(); if (!this._emittedClose) { this._emittedClose = true; this.emit("close"); } if (err.code) { if (~err.code.indexOf("errno 5") || ~err.code.indexOf("EIO")) return; } if (this.listeners("error").length < 2) throw err; }); this._pid = term.pid; this._fd = term.fd; this._pty = term.pty; this._file = file; this._name = name; this._readable = true; this._writable = true; this._socket.on("close", () => { if (this._emittedClose) return; this._emittedClose = true; this._close(); this.emit("close"); }); this._forwardEvents(); } _write(data) { this._socket.write(data); } get fd() { return this._fd; } get ptsName() { return this._pty; } /** * openpty */ static open(opt) { const self = Object.create(UnixTerminal.prototype); opt = opt || {}; if (arguments.length > 1) opt = { cols: arguments[1], rows: arguments[2] }; const cols = opt.cols || DEFAULT_COLS; const rows = opt.rows || DEFAULT_ROWS; const encoding = opt.encoding === void 0 ? "utf8" : opt.encoding; const term = pty.open(cols, rows); self._master = new tty.ReadStream(term.master); if (encoding !== null) self._master.setEncoding(encoding); self._master.resume(); self._slave = new tty.ReadStream(term.slave); if (encoding !== null) self._slave.setEncoding(encoding); self._slave.resume(); self._socket = self._master; self._pid = -1; self._fd = term.master; self._pty = term.pty; self._file = process.argv[0] || "node"; self._name = process.env.TERM || ""; self._readable = true; self._writable = true; self._socket.on("error", (err) => { self._close(); if (self.listeners("error").length < 2) throw err; }); self._socket.on("close", () => { self._close(); }); return self; } destroy() { this._close(); this._socket.once("close", () => { this.kill("SIGHUP"); }); this._socket.destroy(); } kill(signal) { try { process.kill(this.pid, signal || "SIGHUP"); } catch (e) {} } /** * Gets the name of the process. */ get process() { if (process.platform === "darwin") { const title = pty.process(this._fd); return title !== "kernel_task" ? title : this._file; } return pty.process(this._fd, this._pty) || this._file; } /** * TTY */ resize(cols, rows) { if (cols <= 0 || rows <= 0 || isNaN(cols) || isNaN(rows) || cols === Infinity || rows === Infinity) throw new Error("resizing must be done using positive cols and rows"); pty.resize(this._fd, cols, rows); this._cols = cols; this._rows = rows; } clear() {} _sanitizeEnv(env) { delete env["TMUX"]; delete env["TMUX_PANE"]; delete env["STY"]; delete env["WINDOW"]; delete env["WINDOWID"]; delete env["TERMCAP"]; delete env["COLUMNS"]; delete env["LINES"]; } }; }) }); //#endregion //#region src/index.ts init_prebuild_file_path(); let terminalCtor; if (process.platform === "win32") terminalCtor = (init_windowsTerminal(), __toCommonJS(windowsTerminal_exports)).WindowsTerminal; else terminalCtor = (init_unixTerminal(), __toCommonJS(unixTerminal_exports)).UnixTerminal; /** * Forks a process as a pseudoterminal. * @param file The file to launch. * @param args The file's arguments as argv (string[]) or in a pre-escaped * CommandLine format (string). Note that the CommandLine option is only * available on Windows and is expected to be escaped properly. * @param options The options of the terminal. * @throws When the file passed to spawn with does not exists. * @see CommandLineToArgvW https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx * @see Parsing C++ Comamnd-Line Arguments https://msdn.microsoft.com/en-us/library/17w5ykft.aspx * @see GetCommandLine https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx */ function spawn(file, args, opt) { return new terminalCtor(file, args, opt); } /** @deprecated */ function fork(file, args, opt) { return new terminalCtor(file, args, opt); } /** @deprecated */ function createTerminal(file, args, opt) { return new terminalCtor(file, args, opt); } function open(options) { return terminalCtor.open(options); } /** * Expose the native API when not Windows, note that this is not public API and * could be removed at any time. */ const native = process.platform !== "win32" ? __require(ptyPath || "../build/Release/pty.node") : null; //#endregion export { createTerminal, fork, native, open, spawn };