UNPKG

1.7 kBPlain TextView Raw
1import {
2 ChildProcess,
3 spawn as cpSpawn,
4 SpawnOptions as cpSpawnOptions,
5} from 'child_process';
6
7import invariant from 'invariant';
8
9/**
10 * Simplified spawn
11 */
12export function spawn(
13 cmd: string,
14 args: string[] = [],
15 options?: spawn.Options,
16): Promise<void> {
17 return new Promise((resolve, reject) => {
18 invariant(cmd, '"cmd" is required');
19 invariant(Array.isArray(args), '"args" is required and must be an Array');
20
21 const opts = {
22 detached: false,
23 stdio: 'inherit',
24 ...options,
25 };
26 const child = cpSpawn(cmd, args, opts);
27
28 let data = '';
29 if (child.stderr) {
30 child.stderr.on('data', d => {
31 data += d;
32 });
33 }
34
35 child.on('close', code => {
36 if (code) {
37 const e = new spawn.ExitError(`${cmd} exited with code "${code}"`);
38 e.code = code;
39 e.data = data;
40
41 return reject(e);
42 }
43
44 return resolve();
45 });
46
47 if (options && options.detached) {
48 child.unref();
49 /* eslint no-param-reassign: [0] */
50 options.child = child;
51 }
52 });
53}
54
55export namespace spawn {
56 /**
57 * Options for spawn()
58 */
59 export interface Options extends cpSpawnOptions {
60 /**
61 * Indicates if the ChildProcess should be unref()ed
62 */
63 detached?: boolean;
64 /**
65 * {opulated when SpawnOtions.detached is true. Provides a handle to the
66 * ChildProcess.
67 */
68 child?: ChildProcess;
69 }
70
71 /**
72 * Thrown when a spawned command exits non-zero
73 */
74 export class ExitError extends Error {
75 /**
76 * exit code of the ChildProcess
77 */
78 code: number = 0;
79
80 /**
81 * stderr output of the ChildProcess
82 */
83 data: string = '';
84 }
85}