spawn-rx 2.0.8 → 2.0.12

Sign up to get free protection for your applications and to get access to all the features.
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":"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"}
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
- });