| 1 | 'use strict';
|
|---|
| 2 |
|
|---|
| 3 | const nativePromisePrototype = (async () => {})().constructor.prototype;
|
|---|
| 4 | const descriptors = ['then', 'catch', 'finally'].map(property => [
|
|---|
| 5 | property,
|
|---|
| 6 | Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property)
|
|---|
| 7 | ]);
|
|---|
| 8 |
|
|---|
| 9 | // The return value is a mixin of `childProcess` and `Promise`
|
|---|
| 10 | const mergePromise = (spawned, promise) => {
|
|---|
| 11 | for (const [property, descriptor] of descriptors) {
|
|---|
| 12 | // Starting the main `promise` is deferred to avoid consuming streams
|
|---|
| 13 | const value = typeof promise === 'function' ?
|
|---|
| 14 | (...args) => Reflect.apply(descriptor.value, promise(), args) :
|
|---|
| 15 | descriptor.value.bind(promise);
|
|---|
| 16 |
|
|---|
| 17 | Reflect.defineProperty(spawned, property, {...descriptor, value});
|
|---|
| 18 | }
|
|---|
| 19 |
|
|---|
| 20 | return spawned;
|
|---|
| 21 | };
|
|---|
| 22 |
|
|---|
| 23 | // Use promises instead of `child_process` events
|
|---|
| 24 | const getSpawnedPromise = spawned => {
|
|---|
| 25 | return new Promise((resolve, reject) => {
|
|---|
| 26 | spawned.on('exit', (exitCode, signal) => {
|
|---|
| 27 | resolve({exitCode, signal});
|
|---|
| 28 | });
|
|---|
| 29 |
|
|---|
| 30 | spawned.on('error', error => {
|
|---|
| 31 | reject(error);
|
|---|
| 32 | });
|
|---|
| 33 |
|
|---|
| 34 | if (spawned.stdin) {
|
|---|
| 35 | spawned.stdin.on('error', error => {
|
|---|
| 36 | reject(error);
|
|---|
| 37 | });
|
|---|
| 38 | }
|
|---|
| 39 | });
|
|---|
| 40 | };
|
|---|
| 41 |
|
|---|
| 42 | module.exports = {
|
|---|
| 43 | mergePromise,
|
|---|
| 44 | getSpawnedPromise
|
|---|
| 45 | };
|
|---|
| 46 |
|
|---|