diff --git a/package.json b/package.json index acaf0fde9..fb42f5c67 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,6 @@ "ps-list": "^6.0.0", "tslint": "^5.12.1", "tslint-consistent-codestyle": "^1.15.0", - "typescript": "^3.2.2" + "typescript": "3.4" } } diff --git a/src/interfaces.ts b/src/interfaces.ts index 163bc6ded..bf20a89d8 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -107,32 +107,26 @@ export interface ITerminal { once(eventName: string, listener: (...args: any[]) => any): void; } -export interface IPtyForkOptions { +interface IBasePtyForkOptions { name?: string; cols?: number; rows?: number; cwd?: string; env?: { [key: string]: string }; - uid?: number; - gid?: number; encoding?: string; handleFlowControl?: boolean; flowControlPause?: string; flowControlResume?: string; } -export interface IWindowsPtyForkOptions { - name?: string; - cols?: number; - rows?: number; - cwd?: string; - env?: { [key: string]: string }; - encoding?: string; +export interface IPtyForkOptions extends IBasePtyForkOptions { + uid?: number; + gid?: number; +} + +export interface IWindowsPtyForkOptions extends IBasePtyForkOptions { experimentalUseConpty?: boolean; conptyInheritCursor?: boolean; - handleFlowControl?: boolean; - flowControlPause?: string; - flowControlResume?: string; } export interface IPtyOpenOptions { diff --git a/src/terminal.ts b/src/terminal.ts index 88961779d..22bc6bf2b 100644 --- a/src/terminal.ts +++ b/src/terminal.ts @@ -36,7 +36,6 @@ export abstract class Terminal implements ITerminal { protected _writable: boolean; protected _internalee: EventEmitter; - protected _writeMethod: (data: string) => void; private _flowControlPause: string; private _flowControlResume: string; public handleFlowControl: boolean; @@ -75,6 +74,8 @@ export abstract class Terminal implements ITerminal { this._flowControlResume = opt.flowControlResume || FLOW_CONTROL_RESUME; } + protected abstract _write(data: string): void; + public write(data: string): void { if (this.handleFlowControl) { // PAUSE/RESUME messages are not forwarded to the pty @@ -88,7 +89,7 @@ export abstract class Terminal implements ITerminal { } } // everything else goes to the real pty - this._writeMethod(data); + this._write(data); } protected _forwardEvents(): void { diff --git a/src/unixTerminal.ts b/src/unixTerminal.ts index 08f90f795..526adcd5e 100644 --- a/src/unixTerminal.ts +++ b/src/unixTerminal.ts @@ -156,9 +156,10 @@ export class UnixTerminal extends Terminal { }); this._forwardEvents(); + } - // attach write method - this._writeMethod = (data: string) => this._socket.write(data); + protected _write(data: string): void { + this._socket.write(data); } /** diff --git a/src/windowsTerminal.ts b/src/windowsTerminal.ts index 5cc3d64ed..4890d202b 100644 --- a/src/windowsTerminal.ts +++ b/src/windowsTerminal.ts @@ -119,9 +119,14 @@ export class WindowsTerminal extends Terminal { this._writable = true; this._forwardEvents(); + } + + protected _write(data: string): void { + this._defer(this._doWrite, data); + } - // attach write method - this._writeMethod = (data: string) => this._defer(() => this._agent.inSocket.write(data)); + private _doWrite(data: string): void { + this._agent.inSocket.write(data); } /** @@ -163,22 +168,16 @@ export class WindowsTerminal extends Terminal { }); } - private _defer(deferredFn: Function): void { - - // Ensure that this method is only used within Terminal class. - if (!(this instanceof WindowsTerminal)) { - throw new Error('Must be instanceof WindowsTerminal'); - } - + private _defer(deferredFn: (arg?: A) => void, arg?: A): void { // If the terminal is ready, execute. if (this._isReady) { - deferredFn.apply(this, null); + deferredFn.call(this, arg); return; } // Queue until terminal is ready. this._deferreds.push({ - run: () => deferredFn.apply(this, null) + run: () => deferredFn.call(this, arg) }); } diff --git a/typings/node-pty.d.ts b/typings/node-pty.d.ts index 3f95ef840..d7a45db57 100644 --- a/typings/node-pty.d.ts +++ b/typings/node-pty.d.ts @@ -17,37 +17,41 @@ declare module 'node-pty' { */ export function spawn(file: string, args: string[] | string, options: IPtyForkOptions | IWindowsPtyForkOptions): IPty; - export interface IPtyForkOptions { - name?: string; - cols?: number; - rows?: number; - cwd?: string; - env?: { [key: string]: string }; - uid?: number; - gid?: number; - encoding?: string; - } + export interface IBasePtyForkOptions { - export interface IWindowsPtyForkOptions { + /** + * Name of the terminal to be set in environment ($TERM variable). + */ name?: string; + + /** + * Number of intial cols of the pty. + */ cols?: number; + + /** + * Number of initial rows of the pty. + */ rows?: number; + + /** + * Working directory to be set for the slave program. + */ cwd?: string; - env?: { [key: string]: string }; - encoding?: string; + /** - * Whether to use the experimental ConPTY system on Windows. When this is not set, ConPTY will - * be used when the Windows build number is >= 18309 (it's available in 17134 and 17692 but is - * too unstable to enable by default). - * - * This setting does nothing on non-Windows. + * Environment to be set for the slave program. */ - experimentalUseConpty?: boolean; + env?: { [key: string]: string }; + /** - * Whether to use PSEUDOCONSOLE_INHERIT_CURSOR in conpty. - * @see https://docs.microsoft.com/en-us/windows/console/createpseudoconsole + * String encoding of the underlying pty. + * If set, incoming data will be decoded to strings and outgoing strings to bytes applying this encoding. + * If unset, incoming data will be delivered as raw bytes (Buffer type). + * By default 'utf8' is assumed, to unset it explicitly set it to `null`. */ - conptyInheritCursor?: boolean; + encoding?: string; + /** * Whether to enable flow control handling (false by default). If enabled a message of `flowControlPause` * will pause the socket and thus blocking the slave program execution due to buffer back pressure. @@ -57,16 +61,44 @@ declare module 'node-pty' { * the underlying pseudoterminal. */ handleFlowControl?: boolean; + /** * The string that should pause the pty when `handleFlowControl` is true. Default is XOFF ('\x13'). */ flowControlPause?: string; + /** * The string that should resume the pty when `handleFlowControl` is true. Default is XON ('\x11'). */ flowControlResume?: string; } + export interface IPtyForkOptions extends IBasePtyForkOptions { + /** + * Security warning: use this option with great caution, as opened file descriptors + * with higher privileges might leak to the slave program. + */ + uid?: number; + gid?: number; + } + + export interface IWindowsPtyForkOptions extends IBasePtyForkOptions { + /** + * Whether to use the experimental ConPTY system on Windows. When this is not set, ConPTY will + * be used when the Windows build number is >= 18309 (it's available in 17134 and 17692 but is + * too unstable to enable by default). + * + * This setting does nothing on non-Windows. + */ + experimentalUseConpty?: boolean; + + /** + * Whether to use PSEUDOCONSOLE_INHERIT_CURSOR in conpty. + * @see https://docs.microsoft.com/en-us/windows/console/createpseudoconsole + */ + conptyInheritCursor?: boolean; + } + /** * An interface representing a pseudoterminal, on Windows this is emulated via the winpty library. */ diff --git a/yarn.lock b/yarn.lock index 5c5f3a7e4..b81424e30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1172,7 +1172,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^3.2.2: +typescript@3.4: version "3.4.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99" integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==