Skip to content

Commit 6a59ee0

Browse files
committed
Fix promise-fork
1 parent 67e825b commit 6a59ee0

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

src/utils/promise-fork.ts

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
// Copyright (c) npm, Inc.
55
import { fork as builtinFork } from 'node:child_process'
66

7-
import type { ForkOptions as BuiltinForkOptions } from 'node:child_process'
7+
import type {
8+
ForkOptions as BuiltinForkOptions,
9+
StdioOptions
10+
} from 'node:child_process'
811

912
type BuiltinForkResult = ReturnType<typeof builtinFork>
1013

1114
export type ForkOptions = {
1215
cwd?: string
1316
encoding?: BufferEncoding
14-
stdioString?: boolean
17+
stdioString?: boolean | undefined
1518
} & BuiltinForkOptions
1619

1720
export type ForkResult<Output, Extra> = Promise<
@@ -25,6 +28,47 @@ export type ForkResult<Output, Extra> = Promise<
2528
} & Extra
2629
> & { process: BuiltinForkResult; stdio: BuiltinForkResult['stdio'] }
2730

31+
function isPipe(stdio: StdioOptions = 'pipe', fd: number) {
32+
if (stdio === 'pipe' || stdio === null) {
33+
return true
34+
}
35+
if (Array.isArray(stdio)) {
36+
return isPipe((stdio as any)[fd], fd)
37+
}
38+
return false
39+
}
40+
41+
function stdioResult(
42+
stdout: Buffer<ArrayBufferLike>[],
43+
stderr: Buffer<ArrayBufferLike>[],
44+
{
45+
stdio,
46+
stdioString = true
47+
}: { stdioString?: boolean | undefined; stdio?: StdioOptions | undefined }
48+
) {
49+
const result: {
50+
stdout: Buffer<ArrayBufferLike> | string | null
51+
stderr: Buffer<ArrayBufferLike> | string | null
52+
} = {
53+
stdout: null,
54+
stderr: null
55+
}
56+
// stdio is [stdin, stdout, stderr]
57+
if (isPipe(stdio, 1)) {
58+
result.stdout = Buffer.concat(stdout)
59+
if (stdioString) {
60+
result.stdout = result.stdout.toString().trim()
61+
}
62+
}
63+
if (isPipe(stdio, 2)) {
64+
result.stderr = Buffer.concat(stderr)
65+
if (stdioString) {
66+
result.stderr = result.stderr.toString().trim()
67+
}
68+
}
69+
return result
70+
}
71+
2872
export function fork<O extends ForkOptions>(
2973
cmd: string,
3074
args: string[],
@@ -57,8 +101,7 @@ export function fork<O extends ForkOptions>(
57101
cmd,
58102
args,
59103
...result,
60-
stdout: Buffer.concat(stdout).toString(encoding),
61-
stderr: Buffer.concat(stderr).toString(encoding),
104+
...stdioResult(stdout, stderr, builtinForkOptions),
62105
...extra
63106
})
64107

@@ -68,20 +111,16 @@ export function fork<O extends ForkOptions>(
68111
}
69112

70113
const proc = builtinFork(cmd, args, builtinForkOptions)
71-
.on('error', error => rejectWithOpts(error, {}))
114+
.on('error', rejectWithOpts)
72115
.on('close', (code, signal) => {
73-
if (code !== 0 || signal) {
116+
if (code || signal) {
74117
rejectWithOpts(closeError, { code, signal })
75118
} else {
76119
resolve?.(getResult({ code, signal }))
77120
}
78121
})
79-
proc.stdout
80-
?.on('data', chunk => stdout.push(chunk))
81-
.on('error', error => rejectWithOpts(error, {}))
82-
proc.stderr
83-
?.on('data', chunk => stderr.push(chunk))
84-
.on('error', error => rejectWithOpts(error, {}))
122+
proc.stdout?.on('data', c => stdout.push(c)).on('error', rejectWithOpts)
123+
proc.stderr?.on('data', c => stderr.push(c)).on('error', rejectWithOpts)
85124
;(promise as any).stdin = proc.stdin
86125
;(promise as any).process = proc
87126
return promise

0 commit comments

Comments
 (0)