promisify-child-process 4.1.1 → 5.0.0
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/README.md +6 -0
- package/index.cjs +92 -123
- package/index.cjs.map +1 -0
- package/index.d.cts +65 -0
- package/index.d.cts.map +1 -0
- package/index.d.ts +63 -66
- package/index.d.ts.map +1 -0
- package/index.js +141 -0
- package/index.js.map +1 -0
- package/package.json +22 -126
- package/src/index.ts +314 -0
- package/index.js.flow +0 -221
- package/index.mjs +0 -6
package/index.js.flow
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import type { ChildProcess } from 'child_process'
|
|
4
|
-
const child_process = require('child_process')
|
|
5
|
-
|
|
6
|
-
export type ChildProcessOutput = {
|
|
7
|
-
stdout?: ?(string | Buffer),
|
|
8
|
-
stderr?: ?(string | Buffer),
|
|
9
|
-
code?: number | null,
|
|
10
|
-
signal?: string | null,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface ExitReason {
|
|
14
|
-
code?: number | null;
|
|
15
|
-
signal?: string | null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type ErrorWithOutput = Error & ChildProcessOutput
|
|
19
|
-
|
|
20
|
-
export type ChildProcessPromise = ChildProcess & Promise<ChildProcessOutput>
|
|
21
|
-
|
|
22
|
-
type PromisifyChildProcessBaseOpts = {
|
|
23
|
-
encoding?: $PropertyType<child_process$spawnSyncOpts, 'encoding'>,
|
|
24
|
-
killSignal?: $PropertyType<child_process$spawnSyncOpts, 'killSignal'>,
|
|
25
|
-
maxBuffer?: $PropertyType<child_process$spawnSyncOpts, 'maxBuffer'>,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type SpawnOpts = child_process$spawnOpts & PromisifyChildProcessBaseOpts
|
|
29
|
-
export type ForkOpts = child_process$forkOpts & PromisifyChildProcessBaseOpts
|
|
30
|
-
|
|
31
|
-
const bindFinally = <T>(promise: Promise<T>) => (
|
|
32
|
-
handler: () => mixed
|
|
33
|
-
): Promise<T> =>
|
|
34
|
-
// don't assume we're running in an environment with Promise.finally
|
|
35
|
-
promise.then(
|
|
36
|
-
async (value: any): any => {
|
|
37
|
-
await handler()
|
|
38
|
-
return value
|
|
39
|
-
},
|
|
40
|
-
async (reason: any): any => {
|
|
41
|
-
await handler()
|
|
42
|
-
throw reason
|
|
43
|
-
}
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
function joinChunks(
|
|
47
|
-
chunks: $ReadOnlyArray<string | Buffer>,
|
|
48
|
-
encoding: ?string
|
|
49
|
-
): string | Buffer {
|
|
50
|
-
if (chunks[0] instanceof Buffer) {
|
|
51
|
-
const buffer = Buffer.concat((chunks: any))
|
|
52
|
-
if (encoding) return buffer.toString((encoding: any))
|
|
53
|
-
return buffer
|
|
54
|
-
}
|
|
55
|
-
return chunks.join('')
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function promisifyChildProcess(
|
|
59
|
-
child: ChildProcess,
|
|
60
|
-
options: PromisifyChildProcessBaseOpts = {}
|
|
61
|
-
): ChildProcessPromise {
|
|
62
|
-
const _promise = new Promise(
|
|
63
|
-
(
|
|
64
|
-
resolve: (result: ChildProcessOutput) => void,
|
|
65
|
-
reject: (error: ErrorWithOutput) => void
|
|
66
|
-
) => {
|
|
67
|
-
const { encoding, killSignal } = options
|
|
68
|
-
const captureStdio = encoding != null || options.maxBuffer != null
|
|
69
|
-
const maxBuffer =
|
|
70
|
-
options.maxBuffer != null ? options.maxBuffer : 200 * 1024
|
|
71
|
-
|
|
72
|
-
let error: ?ErrorWithOutput
|
|
73
|
-
let bufferSize = 0
|
|
74
|
-
const stdoutChunks: Array<string | Buffer> = []
|
|
75
|
-
const stderrChunks: Array<string | Buffer> = []
|
|
76
|
-
const capture = (chunks: Array<string | Buffer>) => (
|
|
77
|
-
data: string | Buffer
|
|
78
|
-
) => {
|
|
79
|
-
const remaining = Math.max(0, maxBuffer - bufferSize)
|
|
80
|
-
const byteLength = Buffer.byteLength(data, 'utf8')
|
|
81
|
-
bufferSize += Math.min(remaining, byteLength)
|
|
82
|
-
if (byteLength > remaining) {
|
|
83
|
-
error = new Error(`maxBuffer size exceeded`)
|
|
84
|
-
// $FlowFixMe
|
|
85
|
-
child.kill(killSignal ? killSignal : 'SIGTERM')
|
|
86
|
-
data = data.slice(0, remaining)
|
|
87
|
-
}
|
|
88
|
-
chunks.push(data)
|
|
89
|
-
}
|
|
90
|
-
if (captureStdio) {
|
|
91
|
-
if (child.stdout) child.stdout.on('data', capture(stdoutChunks))
|
|
92
|
-
if (child.stderr) child.stderr.on('data', capture(stderrChunks))
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
child.on('error', reject)
|
|
96
|
-
function done(code: ?number, signal: ?string) {
|
|
97
|
-
if (!error) {
|
|
98
|
-
if (code != null && code !== 0) {
|
|
99
|
-
error = new Error(`Process exited with code ${code}`)
|
|
100
|
-
} else if (signal != null) {
|
|
101
|
-
error = new Error(`Process was killed with ${signal}`)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
function defineOutputs(obj: Object) {
|
|
105
|
-
obj.code = code
|
|
106
|
-
obj.signal = signal
|
|
107
|
-
if (captureStdio) {
|
|
108
|
-
obj.stdout = joinChunks(stdoutChunks, encoding)
|
|
109
|
-
obj.stderr = joinChunks(stderrChunks, encoding)
|
|
110
|
-
} else {
|
|
111
|
-
const warn = (prop: 'stdout' | 'stderr') => ({
|
|
112
|
-
configurable: true,
|
|
113
|
-
enumerable: true,
|
|
114
|
-
get(): any {
|
|
115
|
-
/* eslint-disable no-console */
|
|
116
|
-
console.error(
|
|
117
|
-
new Error(
|
|
118
|
-
`To get ${prop} from a spawned or forked process, set the \`encoding\` or \`maxBuffer\` option`
|
|
119
|
-
).stack.replace(/^Error/, 'Warning')
|
|
120
|
-
)
|
|
121
|
-
/* eslint-enable no-console */
|
|
122
|
-
return null
|
|
123
|
-
},
|
|
124
|
-
})
|
|
125
|
-
Object.defineProperties(obj, {
|
|
126
|
-
stdout: warn('stdout'),
|
|
127
|
-
stderr: warn('stderr'),
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
const finalError: ?ErrorWithOutput = error
|
|
132
|
-
if (finalError) {
|
|
133
|
-
defineOutputs(finalError)
|
|
134
|
-
reject(finalError)
|
|
135
|
-
} else {
|
|
136
|
-
const output: ChildProcessOutput = ({}: any)
|
|
137
|
-
defineOutputs(output)
|
|
138
|
-
resolve(output)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
child.on('close', done)
|
|
142
|
-
}
|
|
143
|
-
)
|
|
144
|
-
return (Object.create(child, {
|
|
145
|
-
then: { value: _promise.then.bind(_promise) },
|
|
146
|
-
catch: { value: _promise.catch.bind(_promise) },
|
|
147
|
-
finally: {
|
|
148
|
-
value: bindFinally(_promise),
|
|
149
|
-
},
|
|
150
|
-
}): any)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export function spawn(
|
|
154
|
-
command: string,
|
|
155
|
-
args?: Array<string> | child_process$spawnOpts,
|
|
156
|
-
options?: SpawnOpts
|
|
157
|
-
): ChildProcessPromise {
|
|
158
|
-
return promisifyChildProcess(
|
|
159
|
-
child_process.spawn(command, args, options),
|
|
160
|
-
((Array.isArray(args) ? options : args): any)
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function fork(
|
|
165
|
-
module: string,
|
|
166
|
-
args?: Array<string> | child_process$forkOpts,
|
|
167
|
-
options?: ForkOpts
|
|
168
|
-
): ChildProcessPromise {
|
|
169
|
-
return promisifyChildProcess(
|
|
170
|
-
child_process.fork(module, args, options),
|
|
171
|
-
((Array.isArray(args) ? options : args): any)
|
|
172
|
-
)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function promisifyExecMethod(method: any): any {
|
|
176
|
-
return (...args: Array<any>): ChildProcessPromise => {
|
|
177
|
-
let child: ?ChildProcess
|
|
178
|
-
const _promise = new Promise(
|
|
179
|
-
(
|
|
180
|
-
resolve: (output: ChildProcessOutput) => void,
|
|
181
|
-
reject: (error: ErrorWithOutput) => void
|
|
182
|
-
) => {
|
|
183
|
-
child = method(
|
|
184
|
-
...args,
|
|
185
|
-
(
|
|
186
|
-
err: ?ErrorWithOutput,
|
|
187
|
-
stdout: ?(Buffer | string),
|
|
188
|
-
stderr: ?(Buffer | string)
|
|
189
|
-
) => {
|
|
190
|
-
if (err) {
|
|
191
|
-
err.stdout = stdout
|
|
192
|
-
err.stderr = stderr
|
|
193
|
-
reject(err)
|
|
194
|
-
} else {
|
|
195
|
-
resolve({ code: 0, signal: null, stdout, stderr })
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
)
|
|
199
|
-
}
|
|
200
|
-
)
|
|
201
|
-
if (!child) {
|
|
202
|
-
throw new Error('unexpected error: child has not been initialized')
|
|
203
|
-
}
|
|
204
|
-
return (Object.create((child: any), {
|
|
205
|
-
then: { value: _promise.then.bind(_promise) },
|
|
206
|
-
catch: { value: _promise.catch.bind(_promise) },
|
|
207
|
-
finally: { value: bindFinally(_promise) },
|
|
208
|
-
}): any)
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
export const exec: (
|
|
213
|
-
command: string,
|
|
214
|
-
options?: child_process$execOpts
|
|
215
|
-
) => ChildProcessPromise = promisifyExecMethod(child_process.exec)
|
|
216
|
-
|
|
217
|
-
export const execFile: (
|
|
218
|
-
file: string,
|
|
219
|
-
args?: Array<string> | child_process$execFileOpts,
|
|
220
|
-
options?: child_process$execOpts
|
|
221
|
-
) => ChildProcessPromise = promisifyExecMethod(child_process.execFile)
|