import { EventEmitter } from "events"; import * as stream from "stream"; import { ServerProxy } from "../../common/proxy"; // tslint:disable completed-docs no-any export class WritableProxy extends ServerProxy { public constructor(instance: T, bindEvents: string[] = [], delayedEvents?: string[]) { super({ bindEvents: ["close", "drain", "error", "finish"].concat(bindEvents), doneEvents: ["close"], delayedEvents, instance, }); } public async destroy(): Promise { this.instance.destroy(); } public async end(data?: any, encoding?: string): Promise { return new Promise((resolve): void => { this.instance.end(data, encoding, () => { resolve(); }); }); } public async setDefaultEncoding(encoding: string): Promise { this.instance.setDefaultEncoding(encoding); } public async write(data: any, encoding?: string): Promise { return new Promise((resolve, reject): void => { this.instance.write(data, encoding, (error) => { if (error) { reject(error); } else { resolve(); } }); }); } public async dispose(): Promise { this.instance.end(); await super.dispose(); } } /** * This noise is because we can't do multiple extends and we also can't seem to * do `extends WritableProxy implement ReadableProxy` (for `DuplexProxy`). */ export interface IReadableProxy extends ServerProxy { pipe

(destination: P, options?: { end?: boolean; }): Promise; setEncoding(encoding: string): Promise; } export class ReadableProxy extends ServerProxy implements IReadableProxy { public constructor(instance: T, bindEvents: string[] = []) { super({ bindEvents: ["close", "end", "error"].concat(bindEvents), doneEvents: ["close"], delayedEvents: ["data"], instance, }); } public async pipe

(destination: P, options?: { end?: boolean; }): Promise { this.instance.pipe(destination.instance, options); // `pipe` switches the stream to flowing mode and makes data start emitting. await this.bindDelayedEvent("data"); } public async destroy(): Promise { this.instance.destroy(); } public async setEncoding(encoding: string): Promise { this.instance.setEncoding(encoding); } public async dispose(): Promise { this.instance.destroy(); await super.dispose(); } } export class DuplexProxy extends WritableProxy implements IReadableProxy { public constructor(stream: T, bindEvents: string[] = []) { super(stream, ["end"].concat(bindEvents), ["data"]); } public async pipe

(destination: P, options?: { end?: boolean; }): Promise { this.instance.pipe(destination.instance, options); // `pipe` switches the stream to flowing mode and makes data start emitting. await this.bindDelayedEvent("data"); } public async setEncoding(encoding: string): Promise { this.instance.setEncoding(encoding); } public async dispose(): Promise { this.instance.destroy(); await super.dispose(); } }