2019-01-28 18:14:06 +01:00
|
|
|
import { client } from "@coder/ide/src/fill/client";
|
2019-01-08 01:46:19 +01:00
|
|
|
import { EventEmitter } from "events";
|
|
|
|
import * as nodePty from "node-pty";
|
2019-01-28 18:14:06 +01:00
|
|
|
import { ChildProcess } from "@coder/protocol/src/browser/command";
|
2019-01-08 01:46:19 +01:00
|
|
|
|
|
|
|
type nodePtyType = typeof nodePty;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of nodePty for the browser.
|
|
|
|
*/
|
|
|
|
class Pty implements nodePty.IPty {
|
2019-02-06 18:53:23 +01:00
|
|
|
private readonly emitter = new EventEmitter();
|
2019-01-28 18:14:06 +01:00
|
|
|
private readonly cp: ChildProcess;
|
2019-01-08 01:46:19 +01:00
|
|
|
|
|
|
|
public constructor(file: string, args: string[] | string, options: nodePty.IPtyForkOptions) {
|
2019-01-28 18:14:06 +01:00
|
|
|
this.cp = client.spawn(file, Array.isArray(args) ? args : [args], {
|
|
|
|
...options,
|
|
|
|
tty: {
|
|
|
|
columns: options.cols || 100,
|
|
|
|
rows: options.rows || 100,
|
2019-01-08 01:46:19 +01:00
|
|
|
},
|
|
|
|
});
|
2019-01-28 18:14:06 +01:00
|
|
|
this.on("write", (d) => this.cp.send(d));
|
|
|
|
this.on("kill", (exitCode) => this.cp.kill(exitCode));
|
|
|
|
this.on("resize", (cols, rows) => this.cp.resize!({ columns: cols, rows }));
|
|
|
|
|
|
|
|
this.cp.stdout.on("data", (data) => this.emitter.emit("data", data));
|
|
|
|
this.cp.stderr.on("data", (data) => this.emitter.emit("data", data));
|
|
|
|
this.cp.on("exit", (code) => this.emitter.emit("exit", code));
|
2019-01-08 01:46:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public get pid(): number {
|
2019-01-28 18:14:06 +01:00
|
|
|
return this.cp.pid!;
|
2019-01-08 01:46:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public get process(): string {
|
2019-01-28 18:14:06 +01:00
|
|
|
return this.cp.title!;
|
2019-01-08 01:46:19 +01:00
|
|
|
}
|
|
|
|
|
2019-02-06 18:53:23 +01:00
|
|
|
// tslint:disable-next-line no-any
|
|
|
|
public on(event: string, listener: (...args: any[]) => void): void {
|
2019-01-08 01:46:19 +01:00
|
|
|
this.emitter.on(event, listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
public resize(columns: number, rows: number): void {
|
|
|
|
this.emitter.emit("resize", columns, rows);
|
|
|
|
}
|
|
|
|
|
|
|
|
public write(data: string): void {
|
|
|
|
this.emitter.emit("write", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
public kill(signal?: string): void {
|
|
|
|
this.emitter.emit("kill", signal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ptyType: nodePtyType = {
|
|
|
|
spawn: (file: string, args: string[] | string, options: nodePty.IPtyForkOptions): nodePty.IPty => {
|
|
|
|
return new Pty(file, args, options);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-01-28 18:14:06 +01:00
|
|
|
module.exports = ptyType;
|