spawn-rx 2.0.8 → 2.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.npmignore CHANGED
@@ -1,2 +1,3 @@
1
1
  vendor/jobber/Jobber
2
2
  vendor/jobber/Jobber.sln
3
+ lib/test
package/.travis.yml CHANGED
@@ -3,8 +3,22 @@ dist: trusty
3
3
  os:
4
4
  - linux
5
5
  - osx
6
+ cache:
7
+ directories:
8
+ - node_modules
9
+ notifications:
10
+ email: false
6
11
  language: node_js
7
12
  node_js:
8
- - "6"
9
- - "5"
10
- - "4"
13
+ - 7
14
+ - 6
15
+ - 4
16
+ install:
17
+ - npm install
18
+ branches:
19
+ only:
20
+ - master
21
+ before_script:
22
+ - npm prune
23
+ script:
24
+ - npm run build
package/appveyor.yml CHANGED
@@ -2,10 +2,13 @@
2
2
  platform:
3
3
  - x64
4
4
 
5
+ cache:
6
+ - node_modules
7
+
5
8
  environment:
6
9
  matrix:
10
+ - nodejs_version: "7"
7
11
  - nodejs_version: "6"
8
- - nodejs_version: "5"
9
12
  - nodejs_version: "4"
10
13
 
11
14
  install:
@@ -13,7 +16,6 @@ install:
13
16
  - npm install
14
17
 
15
18
  test_script:
16
- # run tests
17
- - npm test
19
+ - npm run build
18
20
 
19
21
  build: off
package/lib/index.js CHANGED
@@ -136,7 +136,7 @@ function findActualExecutable(exe, args) {
136
136
 
137
137
  if (exe.match(/\.(bat|cmd)$/i)) {
138
138
  let cmd = _path2.default.join(process.env.SYSTEMROOT, 'System32', 'cmd.exe');
139
- let cmdArgs = ['/C', exe, ...args];
139
+ let cmdArgs = ['/C', `${ exe } ${ args.join(' ') }`];
140
140
 
141
141
  return { cmd: cmd, args: cmdArgs };
142
142
  }
@@ -0,0 +1,88 @@
1
+ import 'rxjs/add/observable/of';
2
+ import 'rxjs/add/observable/merge';
3
+ import 'rxjs/add/operator/pluck';
4
+ import 'rxjs/add/operator/reduce';
5
+ import { Observable } from 'rxjs/Observable';
6
+ /**
7
+ * Finds the actual executable and parameters to run on Windows. This method
8
+ * mimics the POSIX behavior of being able to run scripts as executables by
9
+ * replacing the passed-in executable with the script runner, for PowerShell,
10
+ * CMD, and node scripts.
11
+ *
12
+ * This method also does the work of running down PATH, which spawn on Windows
13
+ * also doesn't do, unlike on POSIX.
14
+ *
15
+ * @param {string} exe The executable to run
16
+ * @param {Array<string>} args The arguments to run
17
+ *
18
+ * @return {Object} The cmd and args to run
19
+ * @property {string} cmd The command to pass to spawn
20
+ * @property {Array<string>} args The arguments to pass to spawn
21
+ */
22
+ export declare function findActualExecutable(exe: string, args: Array<string>): {
23
+ cmd: string;
24
+ args: Array<string>;
25
+ };
26
+ /**
27
+ * Spawns a process but detached from the current process. The process is put
28
+ * into its own Process Group that can be killed by unsubscribing from the
29
+ * return Observable.
30
+ *
31
+ * @param {string} exe The executable to run
32
+ * @param {Array<string>} params The parameters to pass to the child
33
+ * @param {Object} opts Options to pass to spawn.
34
+ *
35
+ * @return {Observable<string>} Returns an Observable that when subscribed
36
+ * to, will create a detached process. The
37
+ * process output will be streamed to this
38
+ * Observable, and if unsubscribed from, the
39
+ * process will be terminated early. If the
40
+ * process terminates with a non-zero value,
41
+ * the Observable will terminate with onError.
42
+ */
43
+ export declare function spawnDetached(exe: string, params: Array<string>, opts?: any): Observable<string>;
44
+ /**
45
+ * Spawns a process attached as a child of the current process.
46
+ *
47
+ * @param {string} exe The executable to run
48
+ * @param {Array<string>} params The parameters to pass to the child
49
+ * @param {Object} opts Options to pass to spawn.
50
+ *
51
+ * @return {Observable<string>} Returns an Observable that when subscribed
52
+ * to, will create a child process. The
53
+ * process output will be streamed to this
54
+ * Observable, and if unsubscribed from, the
55
+ * process will be terminated early. If the
56
+ * process terminates with a non-zero value,
57
+ * the Observable will terminate with onError.
58
+ */
59
+ export declare function spawn<T = string>(exe: string, params?: Array<string>, opts?: any): Observable<T>;
60
+ /**
61
+ * Spawns a process but detached from the current process. The process is put
62
+ * into its own Process Group.
63
+ *
64
+ * @param {string} exe The executable to run
65
+ * @param {Array<string>} params The parameters to pass to the child
66
+ * @param {Object} opts Options to pass to spawn.
67
+ *
68
+ * @return {Promise<string>} Returns an Promise that represents a detached
69
+ * process. The value returned is the process
70
+ * output. If the process terminates with a
71
+ * non-zero value, the Promise will resolve with
72
+ * an Error.
73
+ */
74
+ export declare function spawnDetachedPromise(exe: string, params: Array<string>, opts?: any): Promise<string>;
75
+ /**
76
+ * Spawns a process as a child process.
77
+ *
78
+ * @param {string} exe The executable to run
79
+ * @param {Array<string>} params The parameters to pass to the child
80
+ * @param {Object} opts Options to pass to spawn.
81
+ *
82
+ * @return {Promise<string>} Returns an Promise that represents a child
83
+ * process. The value returned is the process
84
+ * output. If the process terminates with a
85
+ * non-zero value, the Promise will resolve with
86
+ * an Error.
87
+ */
88
+ export declare function spawnPromise(exe: string, params: Array<string>, opts?: any): Promise<string>;
@@ -0,0 +1,317 @@
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;
317
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,2BAA6B;AAC7B,yBAA2B;AAC3B,wBAA0B;AAC1B,sCAAwC;AAExC,kCAAgC;AAChC,qCAAmC;AACnC,mCAAiC;AACjC,oCAAkC;AAClC,8CAA6C;AAE7C,kDAAiD;AACjD,kDAAiD;AAIjD,IAAM,OAAO,GAA8B,OAAO,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,qCAAqC;AAChH,IAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE/C,IAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,qCAAqC;AAE7E;;;;;;;GAOG;AACH,6BAA6B,IAAY;IACvC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACX,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,qBAAqB,GAAW;IAC9B,sEAAsE;IACtE,aAAa;IAEb,uDAAuD;IACvD,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,CAAC,sCAAsC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC;IACb,CAAC;IAED,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,EAAE,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,4CAA0C,MAAQ,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9D,GAAG,CAAC,CAAU,UAAQ,EAAR,qBAAQ,EAAR,sBAAQ,EAAR,IAAQ;QAAjB,IAAI,CAAC,iBAAA;QACR,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/B,EAAE,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,MAAM,CAAC;QAChB,CAAC;QAAA,CAAC;KACH;IAED,CAAC,CAAC,4CAA4C,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,8BAAqC,GAAW,EAAE,IAAmB;IAInE,qEAAqE;IACrE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzB,gFAAgF;QAChF,+EAA+E;QAC/E,uCAAuC;QACvC,IAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,GAAG,CAAC,CAAY,UAAY,EAAZ,6BAAY,EAAZ,0BAAY,EAAZ,IAAY;YAAvB,IAAI,GAAG,qBAAA;YACV,IAAI,gBAAgB,GAAG,WAAW,CAAC,KAAG,GAAG,GAAG,GAAK,CAAC,CAAC;YAEnD,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;gBACrC,MAAM,CAAC,oBAAoB,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;YACtD,CAAC;SACF;IACH,CAAC;IAED,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAW,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;QACxG,IAAI,MAAM,GAAG,CAAC,kBAAkB,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAE9F,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IACjD,CAAC;IAED,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACpE,IAAI,OAAO,IAAI,IAAI,EAAE,GAAG,SAAK,IAAI,CAAC,CAAC;QAEnC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;IAED,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC3B,IAAI,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;QAErB,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,CAAC;IAED,YAAY;IACZ,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AA9CD,oDA8CC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,uBAA8B,GAAW,EAAE,MAAqB,EAAE,IAAgB;IAAhB,qBAAA,EAAA,WAAgB;IAC1E,IAAA,sCAAiD,EAA/C,YAAG,EAAE,cAAI,CAAuC;IAExD,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAAA,CAAC;IAEF,IAAM,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAChF,IAAI,OAAO,GAAG,MAAM,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvE,CAAC,CAAC,oBAAkB,MAAM,UAAK,SAAW,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAdD,sCAcC;AAED;;;;;;;;;;;;;;GAcG;AAEH,eAAkC,GAAW,EAAE,MAA0B,EAAE,IAAgB;IAA5C,uBAAA,EAAA,WAA0B;IAAE,qBAAA,EAAA,WAAgB;IACzF,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IAClB,IAAI,QAAQ,GAAG,uBAAU,CAAC,MAAM,CAAC,UAAC,IAG9B;QACI,IAAA,kBAAK,EAAE,0CAAmB,CAAU;QACtC,IAAA,sCAAiD,EAA/C,YAAG,EAAE,cAAI,CAAuC;QACtD,CAAC,CAAC,uBAAqB,GAAG,SAAI,IAAI,CAAC,IAAI,EAAE,UAAK,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAG,CAAC,CAAC;QAClF,IAAI,QAAQ,GAAG,MAAM,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;QAC5C,EAAE,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC;YACzB,OAAO,QAAQ,CAAC,MAAM,CAAC;QACzB,CAAC;QACD,EAAE,CAAC,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC;YACxB,OAAO,QAAQ,CAAC,KAAK,CAAC;QACxB,CAAC;QAAA,CAAC;QAEF,IAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE1C,IAAI,UAAU,GAAG,UAAC,MAAc,IAAK,OAAA,UAAC,CAAkB;YACtD,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjB,MAAM,CAAC;YACT,CAAC;YAAA,CAAC;YACF,IAAI,KAAK,GAAG,qCAAqC,CAAC;YAClD,IAAI,CAAC;gBACH,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;oBAC1B,KAAK,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACvB,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACX,KAAK,GAAG,yCAAuC,GAAG,sBAAiB,CAAC,CAAC,MAAM,OAAI,CAAC;YAClF,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC,EAhBoC,CAgBpC,CAAC;QAEF,IAAI,GAAG,GAAG,IAAI,2BAAY,EAAE,CAAC;QAE7B,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACf,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBACf,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAC1B,UAAC,CAAM,IAAK,OAAA,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAnB,CAAmB,EAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EACrB,cAAM,OAAA,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAhB,CAAgB,CACvB,CAAC,CAAC;YACL,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC,CAAC;YAC9G,CAAC;QACH,CAAC;QAED,IAAI,eAAe,GAAkD,IAAI,CAAC;QAC1E,IAAI,eAAe,GAAkD,IAAI,CAAC;QAC1E,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAChB,eAAe,GAAG,IAAI,2BAAY,EAAW,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,cAAS,eAAqC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,eAAqC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3I,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,eAAe,GAAG,uBAAU,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAChB,eAAe,GAAG,IAAI,2BAAY,EAAW,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,cAAS,eAAqC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,eAAqC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3I,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,eAAe,GAAG,uBAAU,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,CAAQ;YACxB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,IAAY;YAC5B,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,WAAW,GAAG,uBAAU,CAAC,KAAK,CAAC,eAAgB,EAAE,eAAgB,CAAC;iBACnE,MAAM,CAAC,UAAC,GAAG,IAAK,OAAA,GAAG,EAAH,CAAG,EAAE,IAAI,CAAC,CAAC;YAE9B,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBACf,WAAW,CAAC,SAAS,CAAC,cAAM,OAAA,IAAI,CAAC,QAAQ,EAAE,EAAf,CAAe,CAAC,CAAC;YAC/C,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,WAAW,CAAC,SAAS,CAAC,cAAM,OAAA,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,4BAA0B,IAAM,CAAC,CAAC,EAAvD,CAAuD,CAAC,CAAC;YACvF,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,IAAI,2BAAY,CAAC;YACvB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;gBACZ,MAAM,CAAC;YACT,CAAC;YAAA,CAAC;YAEF,CAAC,CAAC,sBAAoB,GAAG,SAAI,IAAI,CAAC,IAAI,EAAI,CAAC,CAAC;YAC5C,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChB,qDAAqD;gBACrD,GAAG,CAAC,OAAO,CAAC,yBAAuB,IAAI,CAAC,GAAK,CAAC,CAAC;gBAC/C,UAAU,CAAC,cAAM,OAAA,IAAI,CAAC,IAAI,EAAE,EAAX,CAAW,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1C,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC,CAAC;QAEJ,MAAM,CAAC,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACxD,CAAC;AA3GD,sBA2GC;AAED,iCAAoC,GAAkB;IACpD,MAAM,CAAC,IAAI,OAAO,CAAS,UAAC,GAAG,EAAE,GAAG;QAClC,IAAI,GAAG,GAAG,EAAE,CAAC;QAEb,GAAG,CAAC,SAAS,CACX,UAAC,CAAC,IAAK,OAAA,GAAG,IAAI,CAAC,EAAR,CAAQ,EACf,UAAC,CAAC,IAAK,OAAA,GAAG,CAAC,IAAI,KAAK,CAAI,GAAG,UAAK,CAAC,CAAC,OAAS,CAAC,CAAC,EAAtC,CAAsC,EAC7C,cAAM,OAAA,GAAG,CAAC,GAAG,CAAC,EAAR,CAAQ,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,8BAAqC,GAAW,EAAE,MAAqB,EAAE,IAAgB;IAAhB,qBAAA,EAAA,WAAgB;IACvF,MAAM,CAAC,uBAAuB,CAAS,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3E,CAAC;AAFD,oDAEC;AAED;;;;;;;;;;;;GAYG;AACH,sBAA6B,GAAW,EAAE,MAAqB,EAAE,IAAgB;IAAhB,qBAAA,EAAA,WAAgB;IAC/E,MAAM,CAAC,uBAAuB,CAAS,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC;AAFD,oCAEC"}
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "spawn-rx",
3
- "version": "2.0.8",
3
+ "version": "2.0.12",
4
4
  "description": "An Rx-version of child_process.spawn",
5
5
  "scripts": {
6
- "doc": "esdoc -c ./esdoc.json",
7
- "compile": "babel -d lib/ src/",
6
+ "doc": "echo \"esdoc may not work correctly\" && esdoc -c ./esdoc.json",
7
+ "compile": "tsc",
8
8
  "prepublish": "npm run compile",
9
- "test": "mocha --compilers js:babel-register ./test/*"
9
+ "lint": "tslint \"src/**/*.ts\" \"test/**/*.ts\"",
10
+ "test": "mocha --compilers ts:ts-node/register ./test/*",
11
+ "build": "npm-run-all compile lint test"
10
12
  },
11
13
  "repository": {
12
14
  "type": "git",
@@ -21,24 +23,31 @@
21
23
  "bugs": {
22
24
  "url": "https://github.com/paulcbetts/spawn-rx/issues"
23
25
  },
24
- "main": "lib/index.js",
26
+ "main": "lib/src/index.js",
27
+ "typings": "lib/src/index.d.ts",
25
28
  "homepage": "https://github.com/paulcbetts/spawn-rx",
26
29
  "dependencies": {
27
30
  "debug": "^2.5.1",
28
- "rxjs": "^5.0.0-rc.5"
31
+ "lodash.assign": "^4.2.0",
32
+ "rxjs": "^5.1.1"
29
33
  },
30
34
  "devDependencies": {
31
- "babel-cli": "^6.18.0",
32
- "babel-eslint": "^7.1.1",
33
- "babel-plugin-transform-async-to-generator": "^6.16.0",
34
- "babel-preset-es2016-node5": "^1.1.2",
35
- "babel-register": "^6.18.0",
36
- "chai": "^3.5.0",
37
- "chai-as-promised": "^6.0.0",
38
- "esdoc": "^0.4.8",
35
+ "@types/chai": "^4.0.4",
36
+ "@types/chai-as-promised": "^7.1.0",
37
+ "@types/mocha": "^2.2.39",
38
+ "@types/node": "^8.0.32",
39
+ "babel-register": "^6.23.0",
40
+ "chai": "^4.1.2",
41
+ "chai-as-promised": "^7.1.1",
42
+ "esdoc": "^0.5.2",
39
43
  "esdoc-es7-plugin": "0.0.3",
40
44
  "esdoc-plugin-async-to-sync": "^0.5.0",
41
- "eslint": "^3.11.1",
42
- "mocha": "^3.2.0"
45
+ "marked": "^0.3.6",
46
+ "mocha": "^4.0.0",
47
+ "npm-run-all": "^4.0.2",
48
+ "ts-node": "^3.3.0",
49
+ "tslint": "^5.7.0",
50
+ "typescript": "^2.5.3",
51
+ "uuid": "3.0.1"
43
52
  }
44
53
  }
@@ -0,0 +1 @@
1
+ declare module 'lodash.assign';
@@ -1,19 +1,23 @@
1
- import path from 'path';
2
- import net from 'net';
3
- import sfs from 'fs';
1
+ import * as path from 'path';
2
+ import * as net from 'net';
3
+ import * as sfs from 'fs';
4
+ import * as assign from 'lodash.assign';
4
5
 
5
6
  import 'rxjs/add/observable/of';
6
7
  import 'rxjs/add/observable/merge';
7
8
  import 'rxjs/add/operator/pluck';
8
9
  import 'rxjs/add/operator/reduce';
9
10
  import { Observable } from 'rxjs/Observable';
11
+ import { Observer } from 'rxjs/Observer';
10
12
  import { Subscription } from 'rxjs/Subscription';
11
13
  import { AsyncSubject } from 'rxjs/AsyncSubject';
14
+ import { Subject } from 'rxjs/Subject';
15
+ import * as childProcess from 'child_process';
12
16
 
13
- const spawnOg = require('child_process').spawn;
17
+ const spawnOg: typeof childProcess.spawn = require('child_process').spawn; //tslint:disable-line:no-var-requires
14
18
  const isWindows = process.platform === 'win32';
15
19
 
16
- const d = require('debug')('spawn-rx');
20
+ const d = require('debug')('spawn-rx'); //tslint:disable-line:no-var-requires
17
21
 
18
22
  /**
19
23
  * stat a file but don't throw if it doesn't exist
@@ -23,7 +27,7 @@ const d = require('debug')('spawn-rx');
23
27
  *
24
28
  * @private
25
29
  */
26
- function statSyncNoException(file) {
30
+ function statSyncNoException(file: string): sfs.Stats | null {
27
31
  try {
28
32
  return sfs.statSync(file);
29
33
  } catch (e) {
@@ -40,7 +44,7 @@ function statSyncNoException(file) {
40
44
  *
41
45
  * @private
42
46
  */
43
- function runDownPath(exe) {
47
+ function runDownPath(exe: string): string {
44
48
  // NB: Windows won't search PATH looking for executables in spawn like
45
49
  // Posix does
46
50
 
@@ -56,10 +60,12 @@ function runDownPath(exe) {
56
60
  return target;
57
61
  }
58
62
 
59
- let haystack = process.env.PATH.split(isWindows ? ';' : ':');
63
+ let haystack = process.env.PATH!.split(isWindows ? ';' : ':');
60
64
  for (let p of haystack) {
61
65
  let needle = path.join(p, exe);
62
- if (statSyncNoException(needle)) return needle;
66
+ if (statSyncNoException(needle)) {
67
+ return needle;
68
+ };
63
69
  }
64
70
 
65
71
  d('Failed to find executable anywhere in path');
@@ -82,9 +88,14 @@ function runDownPath(exe) {
82
88
  * @property {string} cmd The command to pass to spawn
83
89
  * @property {Array<string>} args The arguments to pass to spawn
84
90
  */
85
- export function findActualExecutable(exe, args) {
91
+ export function findActualExecutable(exe: string, args: Array<string>): {
92
+ cmd: string;
93
+ args: Array<string>
94
+ } {
86
95
  // POSIX can just execute scripts directly, no need for silly goosery
87
- if (process.platform !== 'win32') return { cmd: runDownPath(exe), args: args };
96
+ if (process.platform !== 'win32') {
97
+ return { cmd: runDownPath(exe), args: args };
98
+ }
88
99
 
89
100
  if (!sfs.existsSync(exe)) {
90
101
  // NB: When you write something like `surf-client ... -- surf-build` on Windows,
@@ -101,14 +112,14 @@ export function findActualExecutable(exe, args) {
101
112
  }
102
113
 
103
114
  if (exe.match(/\.ps1$/i)) {
104
- let cmd = path.join(process.env.SYSTEMROOT, 'System32', 'WindowsPowerShell', 'v1.0', 'PowerShell.exe');
115
+ let cmd = path.join(process.env.SYSTEMROOT!, 'System32', 'WindowsPowerShell', 'v1.0', 'PowerShell.exe');
105
116
  let psargs = ['-ExecutionPolicy', 'Unrestricted', '-NoLogo', '-NonInteractive', '-File', exe];
106
117
 
107
118
  return { cmd: cmd, args: psargs.concat(args) };
108
119
  }
109
120
 
110
121
  if (exe.match(/\.(bat|cmd)$/i)) {
111
- let cmd = path.join(process.env.SYSTEMROOT, 'System32', 'cmd.exe');
122
+ let cmd = path.join(process.env.SYSTEMROOT!, 'System32', 'cmd.exe');
112
123
  let cmdArgs = ['/C', exe, ...args];
113
124
 
114
125
  return { cmd: cmd, args: cmdArgs };
@@ -142,20 +153,22 @@ export function findActualExecutable(exe, args) {
142
153
  * process terminates with a non-zero value,
143
154
  * the Observable will terminate with onError.
144
155
  */
145
- export function spawnDetached(exe, params, opts=null) {
146
- let { cmd, args } = findActualExecutable(exe, params);
156
+ export function spawnDetached(exe: string, params: Array<string>, opts: any = null): Observable<string> {
157
+ const { cmd, args } = findActualExecutable(exe, params);
158
+
159
+ if (!isWindows) {
160
+ return spawn(cmd, args, assign({}, opts || {}, { detached: true }));
161
+ };
147
162
 
148
- if (!isWindows) return spawn(cmd, args, Object.assign({}, opts || {}, {detached: true }));
149
163
  const newParams = [cmd].concat(args);
150
164
 
151
- let target = path.join(__dirname, '..', 'vendor', 'jobber', 'jobber.exe');
152
- let options = Object.assign({}, opts || {}, { detached: true, jobber: true });
165
+ let target = path.join(__dirname, '..', '..', 'vendor', 'jobber', 'Jobber.exe');
166
+ let options = assign({}, opts || {}, { detached: true, jobber: true });
153
167
 
154
168
  d(`spawnDetached: ${target}, ${newParams}`);
155
169
  return spawn(target, newParams, options);
156
170
  }
157
171
 
158
-
159
172
  /**
160
173
  * Spawns a process attached as a child of the current process.
161
174
  *
@@ -171,30 +184,42 @@ export function spawnDetached(exe, params, opts=null) {
171
184
  * process terminates with a non-zero value,
172
185
  * the Observable will terminate with onError.
173
186
  */
174
- export function spawn(exe, params=[], opts=null) {
175
- opts = opts || {};
176
- let spawnObs = Observable.create((subj) => {
177
- let proc = null;
178
187
 
188
+ export function spawn<T = string>(exe: string, params: Array<string> = [], opts: any = null): Observable<T> {
189
+ opts = opts || {};
190
+ let spawnObs = Observable.create((subj: Observer<{
191
+ source: any,
192
+ text: any
193
+ }>) => {
194
+ let { stdin, ...optsWithoutStdIn } = opts;
179
195
  let { cmd, args } = findActualExecutable(exe, params);
180
- d(`spawning process: ${cmd} ${args.join()}, ${JSON.stringify(opts)}`);
181
- let origOpts = Object.assign({}, opts);
182
- if ('jobber' in origOpts) delete origOpts.jobber;
183
- if ('split' in origOpts) delete origOpts.split;
184
-
196
+ d(`spawning process: ${cmd} ${args.join()}, ${JSON.stringify(optsWithoutStdIn)}`);
197
+ let origOpts = assign({}, optsWithoutStdIn);
198
+ if ('jobber' in origOpts) {
199
+ delete origOpts.jobber;
200
+ }
201
+ if ('split' in origOpts) {
202
+ delete origOpts.split;
203
+ };
185
204
 
186
- proc = spawnOg(cmd, args, origOpts);
205
+ const proc = spawnOg(cmd, args, origOpts);
187
206
 
188
- let bufHandler = (source) => (b) => {
189
- if (b.length < 1) return;
190
- let chunk = "<< String sent back was too long >>";
207
+ let bufHandler = (source: string) => (b: string | Buffer) => {
208
+ if (b.length < 1) {
209
+ return;
210
+ };
211
+ let chunk = '<< String sent back was too long >>';
191
212
  try {
192
- chunk = b.toString();
213
+ if (typeof b === 'string') {
214
+ chunk = b.toString();
215
+ } else {
216
+ chunk = b.toString(origOpts.encoding || 'utf8');
217
+ }
193
218
  } catch (e) {
194
219
  chunk = `<< Lost chunk of process output for ${exe} - length was ${b.length}>>`;
195
220
  }
196
221
 
197
- subj.next({source: source, text: chunk});
222
+ subj.next({ source: source, text: chunk });
198
223
  };
199
224
 
200
225
  let ret = new Subscription();
@@ -202,8 +227,8 @@ export function spawn(exe, params=[], opts=null) {
202
227
  if (opts.stdin) {
203
228
  if (proc.stdin) {
204
229
  ret.add(opts.stdin.subscribe(
205
- (x) => proc.stdin.write(x),
206
- subj.error,
230
+ (x: any) => proc.stdin.write(x),
231
+ subj.error.bind(subj),
207
232
  () => proc.stdin.end()
208
233
  ));
209
234
  } else {
@@ -211,34 +236,34 @@ export function spawn(exe, params=[], opts=null) {
211
236
  }
212
237
  }
213
238
 
214
- let stderrCompleted = null;
215
- let stdoutCompleted = null;
239
+ let stderrCompleted: Subject<boolean> | Observable<boolean> | null = null;
240
+ let stdoutCompleted: Subject<boolean> | Observable<boolean> | null = null;
216
241
  let noClose = false;
217
242
 
218
243
  if (proc.stdout) {
219
- stdoutCompleted = new AsyncSubject();
244
+ stdoutCompleted = new AsyncSubject<boolean>();
220
245
  proc.stdout.on('data', bufHandler('stdout'));
221
- proc.stdout.on('close', () => { stdoutCompleted.next(true); stdoutCompleted.complete(); });
246
+ proc.stdout.on('close', () => { (stdoutCompleted! as Subject<boolean>).next(true); (stdoutCompleted! as Subject<boolean>).complete(); });
222
247
  } else {
223
248
  stdoutCompleted = Observable.of(true);
224
249
  }
225
250
 
226
251
  if (proc.stderr) {
227
- stderrCompleted = new AsyncSubject();
252
+ stderrCompleted = new AsyncSubject<boolean>();
228
253
  proc.stderr.on('data', bufHandler('stderr'));
229
- proc.stderr.on('close', () => { stderrCompleted.next(true); stderrCompleted.complete(); });
254
+ proc.stderr.on('close', () => { (stderrCompleted! as Subject<boolean>).next(true); (stderrCompleted! as Subject<boolean>).complete(); });
230
255
  } else {
231
256
  stderrCompleted = Observable.of(true);
232
257
  }
233
258
 
234
- proc.on('error', (e) => {
259
+ proc.on('error', (e: Error) => {
235
260
  noClose = true;
236
261
  subj.error(e);
237
262
  });
238
263
 
239
- proc.on('close', (code) => {
264
+ proc.on('close', (code: number) => {
240
265
  noClose = true;
241
- let pipesClosed = Observable.merge(stdoutCompleted, stderrCompleted)
266
+ let pipesClosed = Observable.merge(stdoutCompleted!, stderrCompleted!)
242
267
  .reduce((acc) => acc, true);
243
268
 
244
269
  if (code === 0) {
@@ -249,13 +274,15 @@ export function spawn(exe, params=[], opts=null) {
249
274
  });
250
275
 
251
276
  ret.add(new Subscription(() => {
252
- if (noClose) return;
277
+ if (noClose) {
278
+ return;
279
+ };
253
280
 
254
281
  d(`Killing process: ${cmd} ${args.join()}`);
255
282
  if (opts.jobber) {
256
283
  // NB: Connecting to Jobber's named pipe will kill it
257
284
  net.connect(`\\\\.\\pipe\\jobber-${proc.pid}`);
258
- setTimeout(() => proc.kill(), 5*1000);
285
+ setTimeout(() => proc.kill(), 5 * 1000);
259
286
  } else {
260
287
  proc.kill();
261
288
  }
@@ -267,8 +294,8 @@ export function spawn(exe, params=[], opts=null) {
267
294
  return opts.split ? spawnObs : spawnObs.pluck('text');
268
295
  }
269
296
 
270
- function wrapObservableInPromise(obs) {
271
- return new Promise((res, rej) => {
297
+ function wrapObservableInPromise<T>(obs: Observable<T>) {
298
+ return new Promise<string>((res, rej) => {
272
299
  let out = '';
273
300
 
274
301
  obs.subscribe(
@@ -292,11 +319,10 @@ function wrapObservableInPromise(obs) {
292
319
  * non-zero value, the Promise will resolve with
293
320
  * an Error.
294
321
  */
295
- export function spawnDetachedPromise(exe, params, opts=null) {
296
- return wrapObservableInPromise(spawnDetached(exe, params, opts));
322
+ export function spawnDetachedPromise(exe: string, params: Array<string>, opts: any = null): Promise<string> {
323
+ return wrapObservableInPromise<string>(spawnDetached(exe, params, opts));
297
324
  }
298
325
 
299
-
300
326
  /**
301
327
  * Spawns a process as a child process.
302
328
  *
@@ -310,6 +336,6 @@ export function spawnDetachedPromise(exe, params, opts=null) {
310
336
  * non-zero value, the Promise will resolve with
311
337
  * an Error.
312
338
  */
313
- export function spawnPromise(exe, params, opts=null) {
314
- return wrapObservableInPromise(spawn(exe, params, opts));
339
+ export function spawnPromise(exe: string, params: Array<string>, opts: any = null): Promise<string> {
340
+ return wrapObservableInPromise<string>(spawn(exe, params, opts));
315
341
  }
@@ -0,0 +1,15 @@
1
+ import { expect } from 'chai';
2
+ import './support';
3
+
4
+ function delay(ms: number) {
5
+ return new Promise((resolve) => {
6
+ setTimeout(resolve, ms);
7
+ });
8
+ }
9
+
10
+ describe('The test runner', function () {
11
+ it('should pass this test', async function () {
12
+ await delay(1000);
13
+ expect(true).to.be.ok;
14
+ });
15
+ });
@@ -1,3 +1,4 @@
1
+ import { expect } from 'chai';
1
2
  import './support';
2
3
 
3
4
  import { spawn, spawnPromise, spawnDetachedPromise } from '../src/index';
@@ -24,17 +25,24 @@ describe('The spawnDetachedPromise method', function() {
24
25
  });
25
26
  });
26
27
 
27
-
28
- function wrapSplitObservableInPromise(obs) {
28
+ function wrapSplitObservableInPromise(obs: Observable<{
29
+ source: any,
30
+ text: any
31
+ }>): Promise<{
32
+ stderr: string,
33
+ stdout: string,
34
+ error: Error | undefined
35
+ }> {
29
36
  return new Promise((res) => {
30
- let out = {stderr: '', stdout: ''};
37
+ let out = {stderr: '', stdout: '', error: undefined };
31
38
 
32
39
  obs.subscribe(
33
40
  (x) => {
34
- if (x.source === 'stdout')
41
+ if (x.source === 'stdout') {
35
42
  out.stdout += x.text;
36
- else
43
+ } else {
37
44
  out.stderr += x.text;
45
+ }
38
46
  },
39
47
  (e) => { out.error = e; res(out); },
40
48
  () => res(out));
@@ -50,7 +58,7 @@ describe('The spawn method', function() {
50
58
 
51
59
  it('should return split stderr in a inner tag when called with split', async function() {
52
60
  // provide an invalid param to uuid so it complains on stderr
53
- let rxSpawn = spawn('uuid', ['foo'], {split: true});
61
+ let rxSpawn: Observable<{ source: any, text: any }> = spawn('uuid', ['foo'], {split: true}) as any;
54
62
  let result = await wrapSplitObservableInPromise(rxSpawn);
55
63
  expect(result.stderr.length > 10).to.be.ok;
56
64
  expect(result.stdout).to.be.empty;
@@ -58,7 +66,7 @@ describe('The spawn method', function() {
58
66
  });
59
67
 
60
68
  it('should return split stdout in a inner tag when called with split', async function() {
61
- let rxSpawn = spawn('uuid', [], {split: true});
69
+ let rxSpawn: Observable<{ source: any, text: any }> = spawn('uuid', [], {split: true});
62
70
  let result = await wrapSplitObservableInPromise(rxSpawn);
63
71
  expect(result.stdout.match(uuidRegex)).to.be.ok;
64
72
  expect(result.stderr).to.be.empty;
@@ -66,27 +74,27 @@ describe('The spawn method', function() {
66
74
  });
67
75
 
68
76
  it('should ignore stderr if options.stdio = ignore', async function() {
69
- let rxSpawn = spawn('uuid', ['foo'], {split: true, stdio: [null, null, 'ignore']});
77
+ let rxSpawn: Observable<{ source: any, text: any }> = spawn('uuid', ['foo'], {split: true, stdio: [null, null, 'ignore']});
70
78
  let result = await wrapSplitObservableInPromise(rxSpawn);
71
79
  expect(result.stderr).to.be.empty;
72
80
  });
73
81
 
74
82
  it('should ignore stdout if options.stdio = inherit', async function() {
75
- let rxSpawn = spawn('uuid', [], {split: true, stdio: [null, 'inherit', null]});
83
+ let rxSpawn: Observable<{ source: any, text: any }> = spawn('uuid', [], {split: true, stdio: [null, 'inherit', null]});
76
84
  let result = await wrapSplitObservableInPromise(rxSpawn);
77
85
  expect(result.stdout).to.be.empty;
78
86
  });
79
-
87
+
80
88
  it('should croak if stdin is provided but stdio.stdin is disabled', async function() {
81
89
  let stdin = Observable.of('a');
82
- let rxSpawn = spawn('marked', [], {split: true, stdin: stdin, stdio: ['ignore', null, null]});
90
+ let rxSpawn: Observable<{ source: any, text: any }> = spawn('marked', [], {split: true, stdin: stdin, stdio: ['ignore', null, null]});
83
91
  let result = await wrapSplitObservableInPromise(rxSpawn);
84
92
  expect(result.error).to.be.an('error');
85
93
  });
86
-
94
+
87
95
  it('should subscribe to provided stdin', async function() {
88
96
  let stdin = Observable.of('a');
89
- let rxSpawn = spawn('marked', [], {split: true, stdin: stdin});
97
+ let rxSpawn: Observable<{ source: any, text: any }> = spawn('marked', [], {split: true, stdin: stdin});
90
98
  let result = await wrapSplitObservableInPromise(rxSpawn);
91
99
  expect(result.stdout.trim()).to.be.equal('<p>a</p>');
92
100
  });
@@ -1,5 +1,7 @@
1
- let chai = require("chai");
2
- let chaiAsPromised = require("chai-as-promised");
1
+ import * as chai from 'chai';
2
+ import * as chaiAsPromised from 'chai-as-promised';
3
+
4
+ declare const global: any;
3
5
 
4
6
  chai.should();
5
7
  chai.use(chaiAsPromised);
@@ -8,5 +10,5 @@ global.chai = chai;
8
10
  global.chaiAsPromised = chaiAsPromised;
9
11
  global.expect = chai.expect;
10
12
  global.AssertionError = chai.AssertionError;
11
- global.Assertion = chai.Assertion;
12
13
  global.assert = chai.assert;
14
+ global.Assertion = (chai as any).Assertion; //'Assertion' is not existing?
package/tsconfig.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "removeComments": false,
4
+ "preserveConstEnums": true,
5
+ "sourceMap": true,
6
+ "declaration": true,
7
+ "noImplicitAny": true,
8
+ "noImplicitReturns": true,
9
+ "suppressImplicitAnyIndexErrors": true,
10
+ "strictNullChecks": true,
11
+ "noUnusedLocals": true,
12
+ "noImplicitThis": true,
13
+ "noUnusedParameters": true,
14
+ "module": "commonjs",
15
+ "moduleResolution": "node",
16
+ "pretty": true,
17
+ "target": "es5",
18
+ "outDir": "lib",
19
+ "lib": ["dom", "es2015"]
20
+ },
21
+ "formatCodeOptions": {
22
+ "indentSize": 2,
23
+ "tabSize": 2
24
+ },
25
+ "exclude": [
26
+ "node_modules",
27
+ "lib"
28
+ ]
29
+ }
package/tslint.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "rules": {
3
+ "curly": true,
4
+ "eofline": false,
5
+ "align": [true, "parameters"],
6
+ "class-name": true,
7
+ "indent": [true, "spaces"],
8
+ "max-line-length": [true, 150],
9
+ "no-consecutive-blank-lines": [true],
10
+ "no-trailing-whitespace": true,
11
+ "no-duplicate-variable": true,
12
+ "no-var-keyword": true,
13
+ "no-empty": true,
14
+ "no-unused-expression": true,
15
+ "no-use-before-declare": true,
16
+ "no-var-requires": true,
17
+ "one-line": [true,
18
+ "check-else",
19
+ "check-whitespace",
20
+ "check-open-brace"],
21
+ "quotemark": [true,
22
+ "single",
23
+ "avoid-escape"],
24
+ "semicolon": [true, "always"],
25
+ "typedef-whitespace": [true, {
26
+ "call-signature": "nospace",
27
+ "index-signature": "nospace",
28
+ "parameter": "nospace",
29
+ "property-declaration": "nospace",
30
+ "variable-declaration": "nospace"
31
+ }],
32
+ "whitespace": [true,
33
+ "check-branch",
34
+ "check-decl",
35
+ "check-operator",
36
+ "check-type"]
37
+ }
38
+ }
package/.babelrc DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "presets": ["es2016-node5"],
3
- "plugins": ["transform-async-to-generator"]
4
- }
package/.eslintrc DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "parser": "babel-eslint",
3
- "rules": {
4
- "strict": 0,
5
- "indent": [
6
- 2,
7
- 2
8
- ],
9
- "semi": [
10
- 2,
11
- "always"
12
- ],
13
- "no-console": 0
14
- },
15
- "env": {
16
- "es6": true,
17
- "node": true
18
- },
19
- "extends": "eslint:recommended"
20
- }
@@ -1,5 +0,0 @@
1
- 'use strict';
2
-
3
- if (!('regeneratorRuntime' in global)) {
4
- require('babel-polyfill');
5
- }
package/test/.eslintrc DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "parser": "babel-eslint",
3
- "rules": {
4
- "strict": 0,
5
- "indent": [
6
- 2,
7
- 2
8
- ],
9
- "semi": [
10
- 2,
11
- "always"
12
- ],
13
- "no-console": 0
14
- },
15
- "env": {
16
- "es6": true,
17
- "node": true,
18
- "browser": true,
19
- "mocha": true
20
- },
21
- "globals": {
22
- "expect": true,
23
- "chai": true,
24
- },
25
- "extends": "eslint:recommended"
26
- }
@@ -1,14 +0,0 @@
1
- import './support';
2
-
3
- function delay(ms) {
4
- return new Promise((resolve) => {
5
- setTimeout(resolve, ms);
6
- });
7
- }
8
-
9
- describe('The test runner', function() {
10
- it('should pass this test', async function() {
11
- await delay(1000);
12
- expect(true).to.be.ok;
13
- });
14
- });