spawn-rx 2.0.12 → 4.0.0-beta.1

Sign up to get free protection for your applications and to get access to all the features.
package/lib/src/index.js CHANGED
@@ -1,317 +1,337 @@
1
- "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
8
- t[p[i]] = s[p[i]];
9
- return t;
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- var path = require("path");
13
- var net = require("net");
14
- var sfs = require("fs");
15
- var assign = require("lodash.assign");
16
- require("rxjs/add/observable/of");
17
- require("rxjs/add/observable/merge");
18
- require("rxjs/add/operator/pluck");
19
- require("rxjs/add/operator/reduce");
20
- var Observable_1 = require("rxjs/Observable");
21
- var Subscription_1 = require("rxjs/Subscription");
22
- var AsyncSubject_1 = require("rxjs/AsyncSubject");
23
- var spawnOg = require('child_process').spawn; //tslint:disable-line:no-var-requires
24
- var isWindows = process.platform === 'win32';
25
- var d = require('debug')('spawn-rx'); //tslint:disable-line:no-var-requires
26
- /**
27
- * stat a file but don't throw if it doesn't exist
28
- *
29
- * @param {string} file The path to a file
30
- * @return {Stats} The stats structure
31
- *
32
- * @private
33
- */
34
- function statSyncNoException(file) {
35
- try {
36
- return sfs.statSync(file);
37
- }
38
- catch (e) {
39
- return null;
40
- }
41
- }
42
- /**
43
- * Search PATH to see if a file exists in any of the path folders.
44
- *
45
- * @param {string} exe The file to search for
46
- * @return {string} A fully qualified path, or the original path if nothing
47
- * is found
48
- *
49
- * @private
50
- */
51
- function runDownPath(exe) {
52
- // NB: Windows won't search PATH looking for executables in spawn like
53
- // Posix does
54
- // Files with any directory path don't get this applied
55
- if (exe.match(/[\\\/]/)) {
56
- d('Path has slash in directory, bailing');
57
- return exe;
58
- }
59
- var target = path.join('.', exe);
60
- if (statSyncNoException(target)) {
61
- d("Found executable in currect directory: " + target);
62
- return target;
63
- }
64
- var haystack = process.env.PATH.split(isWindows ? ';' : ':');
65
- for (var _i = 0, haystack_1 = haystack; _i < haystack_1.length; _i++) {
66
- var p = haystack_1[_i];
67
- var needle = path.join(p, exe);
68
- if (statSyncNoException(needle)) {
69
- return needle;
70
- }
71
- ;
72
- }
73
- d('Failed to find executable anywhere in path');
74
- return exe;
75
- }
76
- /**
77
- * Finds the actual executable and parameters to run on Windows. This method
78
- * mimics the POSIX behavior of being able to run scripts as executables by
79
- * replacing the passed-in executable with the script runner, for PowerShell,
80
- * CMD, and node scripts.
81
- *
82
- * This method also does the work of running down PATH, which spawn on Windows
83
- * also doesn't do, unlike on POSIX.
84
- *
85
- * @param {string} exe The executable to run
86
- * @param {Array<string>} args The arguments to run
87
- *
88
- * @return {Object} The cmd and args to run
89
- * @property {string} cmd The command to pass to spawn
90
- * @property {Array<string>} args The arguments to pass to spawn
91
- */
92
- function findActualExecutable(exe, args) {
93
- // POSIX can just execute scripts directly, no need for silly goosery
94
- if (process.platform !== 'win32') {
95
- return { cmd: runDownPath(exe), args: args };
96
- }
97
- if (!sfs.existsSync(exe)) {
98
- // NB: When you write something like `surf-client ... -- surf-build` on Windows,
99
- // a shell would normally convert that to surf-build.cmd, but since it's passed
100
- // in as an argument, it doesn't happen
101
- var possibleExts = ['.exe', '.bat', '.cmd', '.ps1'];
102
- for (var _i = 0, possibleExts_1 = possibleExts; _i < possibleExts_1.length; _i++) {
103
- var ext = possibleExts_1[_i];
104
- var possibleFullPath = runDownPath("" + exe + ext);
105
- if (sfs.existsSync(possibleFullPath)) {
106
- return findActualExecutable(possibleFullPath, args);
107
- }
108
- }
109
- }
110
- if (exe.match(/\.ps1$/i)) {
111
- var cmd = path.join(process.env.SYSTEMROOT, 'System32', 'WindowsPowerShell', 'v1.0', 'PowerShell.exe');
112
- var psargs = ['-ExecutionPolicy', 'Unrestricted', '-NoLogo', '-NonInteractive', '-File', exe];
113
- return { cmd: cmd, args: psargs.concat(args) };
114
- }
115
- if (exe.match(/\.(bat|cmd)$/i)) {
116
- var cmd = path.join(process.env.SYSTEMROOT, 'System32', 'cmd.exe');
117
- var cmdArgs = ['/C', exe].concat(args);
118
- return { cmd: cmd, args: cmdArgs };
119
- }
120
- if (exe.match(/\.(js)$/i)) {
121
- var cmd = process.execPath;
122
- var nodeArgs = [exe];
123
- return { cmd: cmd, args: nodeArgs.concat(args) };
124
- }
125
- // Dunno lol
126
- return { cmd: exe, args: args };
127
- }
128
- exports.findActualExecutable = findActualExecutable;
129
- /**
130
- * Spawns a process but detached from the current process. The process is put
131
- * into its own Process Group that can be killed by unsubscribing from the
132
- * return Observable.
133
- *
134
- * @param {string} exe The executable to run
135
- * @param {Array<string>} params The parameters to pass to the child
136
- * @param {Object} opts Options to pass to spawn.
137
- *
138
- * @return {Observable<string>} Returns an Observable that when subscribed
139
- * to, will create a detached process. The
140
- * process output will be streamed to this
141
- * Observable, and if unsubscribed from, the
142
- * process will be terminated early. If the
143
- * process terminates with a non-zero value,
144
- * the Observable will terminate with onError.
145
- */
146
- function spawnDetached(exe, params, opts) {
147
- if (opts === void 0) { opts = null; }
148
- var _a = findActualExecutable(exe, params), cmd = _a.cmd, args = _a.args;
149
- if (!isWindows) {
150
- return spawn(cmd, args, assign({}, opts || {}, { detached: true }));
151
- }
152
- ;
153
- var newParams = [cmd].concat(args);
154
- var target = path.join(__dirname, '..', '..', 'vendor', 'jobber', 'Jobber.exe');
155
- var options = assign({}, opts || {}, { detached: true, jobber: true });
156
- d("spawnDetached: " + target + ", " + newParams);
157
- return spawn(target, newParams, options);
158
- }
159
- exports.spawnDetached = spawnDetached;
160
- /**
161
- * Spawns a process attached as a child of the current process.
162
- *
163
- * @param {string} exe The executable to run
164
- * @param {Array<string>} params The parameters to pass to the child
165
- * @param {Object} opts Options to pass to spawn.
166
- *
167
- * @return {Observable<string>} Returns an Observable that when subscribed
168
- * to, will create a child process. The
169
- * process output will be streamed to this
170
- * Observable, and if unsubscribed from, the
171
- * process will be terminated early. If the
172
- * process terminates with a non-zero value,
173
- * the Observable will terminate with onError.
174
- */
175
- function spawn(exe, params, opts) {
176
- if (params === void 0) { params = []; }
177
- if (opts === void 0) { opts = null; }
178
- opts = opts || {};
179
- var spawnObs = Observable_1.Observable.create(function (subj) {
180
- var stdin = opts.stdin, optsWithoutStdIn = __rest(opts, ["stdin"]);
181
- var _a = findActualExecutable(exe, params), cmd = _a.cmd, args = _a.args;
182
- d("spawning process: " + cmd + " " + args.join() + ", " + JSON.stringify(optsWithoutStdIn));
183
- var origOpts = assign({}, optsWithoutStdIn);
184
- if ('jobber' in origOpts) {
185
- delete origOpts.jobber;
186
- }
187
- if ('split' in origOpts) {
188
- delete origOpts.split;
189
- }
190
- ;
191
- var proc = spawnOg(cmd, args, origOpts);
192
- var bufHandler = function (source) { return function (b) {
193
- if (b.length < 1) {
194
- return;
195
- }
196
- ;
197
- var chunk = '<< String sent back was too long >>';
198
- try {
199
- if (typeof b === 'string') {
200
- chunk = b.toString();
201
- }
202
- else {
203
- chunk = b.toString(origOpts.encoding || 'utf8');
204
- }
205
- }
206
- catch (e) {
207
- chunk = "<< Lost chunk of process output for " + exe + " - length was " + b.length + ">>";
208
- }
209
- subj.next({ source: source, text: chunk });
210
- }; };
211
- var ret = new Subscription_1.Subscription();
212
- if (opts.stdin) {
213
- if (proc.stdin) {
214
- ret.add(opts.stdin.subscribe(function (x) { return proc.stdin.write(x); }, subj.error.bind(subj), function () { return proc.stdin.end(); }));
215
- }
216
- else {
217
- subj.error(new Error("opts.stdio conflicts with provided spawn opts.stdin observable, 'pipe' is required"));
218
- }
219
- }
220
- var stderrCompleted = null;
221
- var stdoutCompleted = null;
222
- var noClose = false;
223
- if (proc.stdout) {
224
- stdoutCompleted = new AsyncSubject_1.AsyncSubject();
225
- proc.stdout.on('data', bufHandler('stdout'));
226
- proc.stdout.on('close', function () { stdoutCompleted.next(true); stdoutCompleted.complete(); });
227
- }
228
- else {
229
- stdoutCompleted = Observable_1.Observable.of(true);
230
- }
231
- if (proc.stderr) {
232
- stderrCompleted = new AsyncSubject_1.AsyncSubject();
233
- proc.stderr.on('data', bufHandler('stderr'));
234
- proc.stderr.on('close', function () { stderrCompleted.next(true); stderrCompleted.complete(); });
235
- }
236
- else {
237
- stderrCompleted = Observable_1.Observable.of(true);
238
- }
239
- proc.on('error', function (e) {
240
- noClose = true;
241
- subj.error(e);
242
- });
243
- proc.on('close', function (code) {
244
- noClose = true;
245
- var pipesClosed = Observable_1.Observable.merge(stdoutCompleted, stderrCompleted)
246
- .reduce(function (acc) { return acc; }, true);
247
- if (code === 0) {
248
- pipesClosed.subscribe(function () { return subj.complete(); });
249
- }
250
- else {
251
- pipesClosed.subscribe(function () { return subj.error(new Error("Failed with exit code: " + code)); });
252
- }
253
- });
254
- ret.add(new Subscription_1.Subscription(function () {
255
- if (noClose) {
256
- return;
257
- }
258
- ;
259
- d("Killing process: " + cmd + " " + args.join());
260
- if (opts.jobber) {
261
- // NB: Connecting to Jobber's named pipe will kill it
262
- net.connect("\\\\.\\pipe\\jobber-" + proc.pid);
263
- setTimeout(function () { return proc.kill(); }, 5 * 1000);
264
- }
265
- else {
266
- proc.kill();
267
- }
268
- }));
269
- return ret;
270
- });
271
- return opts.split ? spawnObs : spawnObs.pluck('text');
272
- }
273
- exports.spawn = spawn;
274
- function wrapObservableInPromise(obs) {
275
- return new Promise(function (res, rej) {
276
- var out = '';
277
- obs.subscribe(function (x) { return out += x; }, function (e) { return rej(new Error(out + "\n" + e.message)); }, function () { return res(out); });
278
- });
279
- }
280
- /**
281
- * Spawns a process but detached from the current process. The process is put
282
- * into its own Process Group.
283
- *
284
- * @param {string} exe The executable to run
285
- * @param {Array<string>} params The parameters to pass to the child
286
- * @param {Object} opts Options to pass to spawn.
287
- *
288
- * @return {Promise<string>} Returns an Promise that represents a detached
289
- * process. The value returned is the process
290
- * output. If the process terminates with a
291
- * non-zero value, the Promise will resolve with
292
- * an Error.
293
- */
294
- function spawnDetachedPromise(exe, params, opts) {
295
- if (opts === void 0) { opts = null; }
296
- return wrapObservableInPromise(spawnDetached(exe, params, opts));
297
- }
298
- exports.spawnDetachedPromise = spawnDetachedPromise;
299
- /**
300
- * Spawns a process as a child process.
301
- *
302
- * @param {string} exe The executable to run
303
- * @param {Array<string>} params The parameters to pass to the child
304
- * @param {Object} opts Options to pass to spawn.
305
- *
306
- * @return {Promise<string>} Returns an Promise that represents a child
307
- * process. The value returned is the process
308
- * output. If the process terminates with a
309
- * non-zero value, the Promise will resolve with
310
- * an Error.
311
- */
312
- function spawnPromise(exe, params, opts) {
313
- if (opts === void 0) { opts = null; }
314
- return wrapObservableInPromise(spawn(exe, params, opts));
315
- }
316
- exports.spawnPromise = spawnPromise;
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.findActualExecutable = findActualExecutable;
24
+ exports.spawnDetached = spawnDetached;
25
+ exports.spawn = spawn;
26
+ exports.spawnDetachedPromise = spawnDetachedPromise;
27
+ exports.spawnPromise = spawnPromise;
28
+ /* eslint-disable @typescript-eslint/no-explicit-any */
29
+ var path = require("path");
30
+ var net = require("net");
31
+ var sfs = require("fs");
32
+ var assign = require("lodash.assign");
33
+ var rxjs_1 = require("rxjs");
34
+ var operators_1 = require("rxjs/operators");
35
+ var child_process_1 = require("child_process");
36
+ var debug_1 = require("debug");
37
+ var isWindows = process.platform === "win32";
38
+ var d = (0, debug_1.default)("spawn-rx"); // tslint:disable-line:no-var-requires
39
+ /**
40
+ * stat a file but don't throw if it doesn't exist
41
+ *
42
+ * @param {string} file The path to a file
43
+ * @return {Stats} The stats structure
44
+ *
45
+ * @private
46
+ */
47
+ function statSyncNoException(file) {
48
+ try {
49
+ return sfs.statSync(file);
50
+ }
51
+ catch (_a) {
52
+ return null;
53
+ }
54
+ }
55
+ /**
56
+ * Search PATH to see if a file exists in any of the path folders.
57
+ *
58
+ * @param {string} exe The file to search for
59
+ * @return {string} A fully qualified path, or the original path if nothing
60
+ * is found
61
+ *
62
+ * @private
63
+ */
64
+ function runDownPath(exe) {
65
+ // NB: Windows won't search PATH looking for executables in spawn like
66
+ // Posix does
67
+ // Files with any directory path don't get this applied
68
+ if (exe.match(/[\\/]/)) {
69
+ d("Path has slash in directory, bailing");
70
+ return exe;
71
+ }
72
+ var target = path.join(".", exe);
73
+ if (statSyncNoException(target)) {
74
+ d("Found executable in currect directory: ".concat(target));
75
+ return target;
76
+ }
77
+ var haystack = process.env.PATH.split(isWindows ? ";" : ":");
78
+ for (var _i = 0, haystack_1 = haystack; _i < haystack_1.length; _i++) {
79
+ var p = haystack_1[_i];
80
+ var needle = path.join(p, exe);
81
+ if (statSyncNoException(needle)) {
82
+ return needle;
83
+ }
84
+ }
85
+ d("Failed to find executable anywhere in path");
86
+ return exe;
87
+ }
88
+ /**
89
+ * Finds the actual executable and parameters to run on Windows. This method
90
+ * mimics the POSIX behavior of being able to run scripts as executables by
91
+ * replacing the passed-in executable with the script runner, for PowerShell,
92
+ * CMD, and node scripts.
93
+ *
94
+ * This method also does the work of running down PATH, which spawn on Windows
95
+ * also doesn't do, unlike on POSIX.
96
+ *
97
+ * @param {string} exe The executable to run
98
+ * @param {Array<string>} args The arguments to run
99
+ *
100
+ * @return {Object} The cmd and args to run
101
+ * @property {string} cmd The command to pass to spawn
102
+ * @property {Array<string>} args The arguments to pass to spawn
103
+ */
104
+ function findActualExecutable(exe, args) {
105
+ // POSIX can just execute scripts directly, no need for silly goosery
106
+ if (process.platform !== "win32") {
107
+ return { cmd: runDownPath(exe), args: args };
108
+ }
109
+ if (!sfs.existsSync(exe)) {
110
+ // NB: When you write something like `surf-client ... -- surf-build` on Windows,
111
+ // a shell would normally convert that to surf-build.cmd, but since it's passed
112
+ // in as an argument, it doesn't happen
113
+ var possibleExts = [".exe", ".bat", ".cmd", ".ps1"];
114
+ for (var _i = 0, possibleExts_1 = possibleExts; _i < possibleExts_1.length; _i++) {
115
+ var ext = possibleExts_1[_i];
116
+ var possibleFullPath = runDownPath("".concat(exe).concat(ext));
117
+ if (sfs.existsSync(possibleFullPath)) {
118
+ return findActualExecutable(possibleFullPath, args);
119
+ }
120
+ }
121
+ }
122
+ if (exe.match(/\.ps1$/i)) {
123
+ var cmd = path.join(process.env.SYSTEMROOT, "System32", "WindowsPowerShell", "v1.0", "PowerShell.exe");
124
+ var psargs = [
125
+ "-ExecutionPolicy",
126
+ "Unrestricted",
127
+ "-NoLogo",
128
+ "-NonInteractive",
129
+ "-File",
130
+ exe,
131
+ ];
132
+ return { cmd: cmd, args: psargs.concat(args) };
133
+ }
134
+ if (exe.match(/\.(bat|cmd)$/i)) {
135
+ var cmd = path.join(process.env.SYSTEMROOT, "System32", "cmd.exe");
136
+ var cmdArgs = __spreadArray(["/C", exe], args, true);
137
+ return { cmd: cmd, args: cmdArgs };
138
+ }
139
+ if (exe.match(/\.(js)$/i)) {
140
+ var cmd = process.execPath;
141
+ var nodeArgs = [exe];
142
+ return { cmd: cmd, args: nodeArgs.concat(args) };
143
+ }
144
+ // Dunno lol
145
+ return { cmd: exe, args: args };
146
+ }
147
+ /**
148
+ * Spawns a process but detached from the current process. The process is put
149
+ * into its own Process Group that can be killed by unsubscribing from the
150
+ * return Observable.
151
+ *
152
+ * @param {string} exe The executable to run
153
+ * @param {Array<string>} params The parameters to pass to the child
154
+ * @param {Object} opts Options to pass to spawn.
155
+ *
156
+ * @return {Observable<string>} Returns an Observable that when subscribed
157
+ * to, will create a detached process. The
158
+ * process output will be streamed to this
159
+ * Observable, and if unsubscribed from, the
160
+ * process will be terminated early. If the
161
+ * process terminates with a non-zero value,
162
+ * the Observable will terminate with onError.
163
+ */
164
+ function spawnDetached(exe, params, opts) {
165
+ if (opts === void 0) { opts = null; }
166
+ var _a = findActualExecutable(exe, params), cmd = _a.cmd, args = _a.args;
167
+ if (!isWindows) {
168
+ return spawn(cmd, args, assign({}, opts || {}, { detached: true }));
169
+ }
170
+ var newParams = [cmd].concat(args);
171
+ var target = path.join(__dirname, "..", "..", "vendor", "jobber", "Jobber.exe");
172
+ var options = assign({}, opts || {}, { detached: true, jobber: true });
173
+ d("spawnDetached: ".concat(target, ", ").concat(newParams));
174
+ return spawn(target, newParams, options);
175
+ }
176
+ /**
177
+ * Spawns a process attached as a child of the current process.
178
+ *
179
+ * @param {string} exe The executable to run
180
+ * @param {Array<string>} params The parameters to pass to the child
181
+ * @param {Object} opts Options to pass to spawn.
182
+ *
183
+ * @return {Observable<string>} Returns an Observable that when subscribed
184
+ * to, will create a child process. The
185
+ * process output will be streamed to this
186
+ * Observable, and if unsubscribed from, the
187
+ * process will be terminated early. If the
188
+ * process terminates with a non-zero value,
189
+ * the Observable will terminate with onError.
190
+ */
191
+ function spawn(exe, params, opts) {
192
+ if (params === void 0) { params = []; }
193
+ if (opts === void 0) { opts = null; }
194
+ opts = opts || {};
195
+ var spawnObs = rxjs_1.Observable.create(function (subj) {
196
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
197
+ var _ = opts._, optsWithoutStdIn = __rest(opts, ["_"]);
198
+ var _a = findActualExecutable(exe, params), cmd = _a.cmd, args = _a.args;
199
+ d("spawning process: ".concat(cmd, " ").concat(args.join(), ", ").concat(JSON.stringify(optsWithoutStdIn)));
200
+ var origOpts = assign({}, optsWithoutStdIn);
201
+ if ("jobber" in origOpts) {
202
+ delete origOpts.jobber;
203
+ }
204
+ if ("split" in origOpts) {
205
+ delete origOpts.split;
206
+ }
207
+ var proc = (0, child_process_1.spawn)(cmd, args, origOpts);
208
+ var bufHandler = function (source) { return function (b) {
209
+ if (b.length < 1) {
210
+ return;
211
+ }
212
+ var chunk = "<< String sent back was too long >>";
213
+ try {
214
+ if (typeof b === "string") {
215
+ chunk = b.toString();
216
+ }
217
+ else {
218
+ chunk = b.toString(origOpts.encoding || "utf8");
219
+ }
220
+ }
221
+ catch (_a) {
222
+ chunk = "<< Lost chunk of process output for ".concat(exe, " - length was ").concat(b.length, ">>");
223
+ }
224
+ subj.next({ source: source, text: chunk });
225
+ }; };
226
+ var ret = new rxjs_1.Subscription();
227
+ if (opts.stdin) {
228
+ if (proc.stdin) {
229
+ ret.add(opts.stdin.subscribe(function (x) { return proc.stdin.write(x); }, subj.error.bind(subj), function () { return proc.stdin.end(); }));
230
+ }
231
+ else {
232
+ subj.error(new Error("opts.stdio conflicts with provided spawn opts.stdin observable, 'pipe' is required"));
233
+ }
234
+ }
235
+ var stderrCompleted = null;
236
+ var stdoutCompleted = null;
237
+ var noClose = false;
238
+ if (proc.stdout) {
239
+ stdoutCompleted = new rxjs_1.AsyncSubject();
240
+ proc.stdout.on("data", bufHandler("stdout"));
241
+ proc.stdout.on("close", function () {
242
+ stdoutCompleted.next(true);
243
+ stdoutCompleted.complete();
244
+ });
245
+ }
246
+ else {
247
+ stdoutCompleted = (0, rxjs_1.of)(true);
248
+ }
249
+ if (proc.stderr) {
250
+ stderrCompleted = new rxjs_1.AsyncSubject();
251
+ proc.stderr.on("data", bufHandler("stderr"));
252
+ proc.stderr.on("close", function () {
253
+ stderrCompleted.next(true);
254
+ stderrCompleted.complete();
255
+ });
256
+ }
257
+ else {
258
+ stderrCompleted = (0, rxjs_1.of)(true);
259
+ }
260
+ proc.on("error", function (e) {
261
+ noClose = true;
262
+ subj.error(e);
263
+ });
264
+ proc.on("close", function (code) {
265
+ noClose = true;
266
+ var pipesClosed = (0, rxjs_1.merge)(stdoutCompleted, stderrCompleted).pipe((0, operators_1.reduce)(function (acc) { return acc; }, true));
267
+ if (code === 0) {
268
+ pipesClosed.subscribe(function () { return subj.complete(); });
269
+ }
270
+ else {
271
+ pipesClosed.subscribe(function () {
272
+ var e = new Error("Failed with exit code: ".concat(code));
273
+ e.exitCode = code;
274
+ subj.error(e);
275
+ });
276
+ }
277
+ });
278
+ ret.add(new rxjs_1.Subscription(function () {
279
+ if (noClose) {
280
+ return;
281
+ }
282
+ d("Killing process: ".concat(cmd, " ").concat(args.join()));
283
+ if (opts.jobber) {
284
+ // NB: Connecting to Jobber's named pipe will kill it
285
+ net.connect("\\\\.\\pipe\\jobber-".concat(proc.pid));
286
+ setTimeout(function () { return proc.kill(); }, 5 * 1000);
287
+ }
288
+ else {
289
+ proc.kill();
290
+ }
291
+ }));
292
+ return ret;
293
+ });
294
+ return opts.split ? spawnObs : spawnObs.pipe((0, operators_1.map)(function (x) { return x === null || x === void 0 ? void 0 : x.text; }));
295
+ }
296
+ function wrapObservableInPromise(obs) {
297
+ return new Promise(function (res, rej) {
298
+ var out = "";
299
+ obs.subscribe(function (x) { return (out += x); }, function (e) { return rej(new Error("".concat(out, "\n").concat(e.message))); }, function () { return res(out); });
300
+ });
301
+ }
302
+ /**
303
+ * Spawns a process but detached from the current process. The process is put
304
+ * into its own Process Group.
305
+ *
306
+ * @param {string} exe The executable to run
307
+ * @param {Array<string>} params The parameters to pass to the child
308
+ * @param {Object} opts Options to pass to spawn.
309
+ *
310
+ * @return {Promise<string>} Returns an Promise that represents a detached
311
+ * process. The value returned is the process
312
+ * output. If the process terminates with a
313
+ * non-zero value, the Promise will resolve with
314
+ * an Error.
315
+ */
316
+ function spawnDetachedPromise(exe, params, opts) {
317
+ if (opts === void 0) { opts = null; }
318
+ return wrapObservableInPromise(spawnDetached(exe, params, opts));
319
+ }
320
+ /**
321
+ * Spawns a process as a child process.
322
+ *
323
+ * @param {string} exe The executable to run
324
+ * @param {Array<string>} params The parameters to pass to the child
325
+ * @param {Object} opts Options to pass to spawn.
326
+ *
327
+ * @return {Promise<string>} Returns an Promise that represents a child
328
+ * process. The value returned is the process
329
+ * output. If the process terminates with a
330
+ * non-zero value, the Promise will resolve with
331
+ * an Error.
332
+ */
333
+ function spawnPromise(exe, params, opts) {
334
+ if (opts === void 0) { opts = null; }
335
+ return wrapObservableInPromise(spawn(exe, params, opts));
336
+ }
317
337
  //# sourceMappingURL=index.js.map