@karinjs/node-pty
Version:
Fork pseudoterminals in Node.JS
903 lines (891 loc) • 26.8 kB
JavaScript
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 };