/// /// /// /// import { ChildProcess as BaseChildProcess, MessageOptions, SendHandle, SpawnOptions } from 'child_process'; import * as Rx from 'rxjs'; import { EventEmitter, Writable } from 'stream'; /** * Identifier for a command; if string, it's the command's name, if number, it's the index. */ export type CommandIdentifier = string | number; export interface CommandInfo { /** * Command's name. */ name: string; /** * Which command line the command has. */ command: string; /** * Which environment variables should the spawned process have. */ env?: Record; /** * The current working directory of the process when spawned. */ cwd?: string; /** * Color to use on prefix of the command. */ prefixColor?: string; /** * Whether sending of messages to/from this command (also known as "inter-process communication") * should be enabled, and using which file descriptor number. * * If set, must be > 2. */ ipc?: number; /** * Output command in raw format. */ raw?: boolean; } export interface CloseEvent { command: CommandInfo; /** * The command's index among all commands ran. */ index: number; /** * Whether the command exited because it was killed. */ killed: boolean; /** * The exit code or signal for the command. */ exitCode: string | number; timings: { startDate: Date; endDate: Date; durationSeconds: number; }; } export interface TimerEvent { startDate: Date; endDate?: Date; } export interface MessageEvent { message: object; handle?: SendHandle; } interface OutgoingMessageEvent extends MessageEvent { options?: MessageOptions; onSent(error?: unknown): void; } /** * Subtype of NodeJS's child_process including only what's actually needed for a command to work. */ export type ChildProcess = EventEmitter & Pick; /** * Interface for a function that must kill the process with `pid`, optionally sending `signal` to it. */ export type KillProcess = (pid: number, signal?: string) => void; /** * Interface for a function that spawns a command and returns its child process instance. */ export type SpawnCommand = (command: string, options: SpawnOptions) => ChildProcess; /** * The state of a command. * * - `stopped`: command was never started * - `started`: command is currently running * - `errored`: command failed spawning * - `exited`: command is not running anymore, e.g. it received a close event */ type CommandState = 'stopped' | 'started' | 'errored' | 'exited'; export declare class Command implements CommandInfo { private readonly killProcess; private readonly spawn; private readonly spawnOpts; readonly index: number; /** @inheritdoc */ readonly name: string; /** @inheritdoc */ readonly command: string; /** @inheritdoc */ readonly prefixColor?: string; /** @inheritdoc */ readonly env: Record; /** @inheritdoc */ readonly cwd?: string; /** @inheritdoc */ readonly ipc?: number; readonly close: Rx.Subject; readonly error: Rx.Subject; readonly stdout: Rx.Subject; readonly stderr: Rx.Subject; readonly timer: Rx.Subject; readonly messages: { incoming: Rx.Subject; outgoing: Rx.ReplaySubject; }; process?: ChildProcess; private subscriptions; stdin?: Writable; pid?: number; killed: boolean; exited: boolean; state: CommandState; constructor({ index, name, command, prefixColor, env, cwd, ipc }: CommandInfo & { index: number; }, spawnOpts: SpawnOptions, spawn: SpawnCommand, killProcess: KillProcess); /** * Starts this command, piping output, error and close events onto the corresponding observables. */ start(): void; private maybeSetupIPC; /** * Sends a message to the underlying process once it starts. * * @throws If the command doesn't have an IPC channel enabled * @returns Promise that resolves when the message is sent, * or rejects if it fails to deliver the message. */ send(message: object, handle?: SendHandle, options?: MessageOptions): Promise; /** * Kills this command, optionally specifying a signal to send to it. */ kill(code?: string): void; private cleanUp; /** * Detects whether a command can be killed. * * Also works as a type guard on the input `command`. */ static canKill(command: Command): command is Command & { pid: number; process: ChildProcess; }; } export {};