4
4
// Copyright (c) npm, Inc.
5
5
import { fork as builtinFork } from 'node:child_process'
6
6
7
- import type { ForkOptions as BuiltinForkOptions } from 'node:child_process'
7
+ import type {
8
+ ForkOptions as BuiltinForkOptions ,
9
+ StdioOptions
10
+ } from 'node:child_process'
8
11
9
12
type BuiltinForkResult = ReturnType < typeof builtinFork >
10
13
11
14
export type ForkOptions = {
12
15
cwd ?: string
13
16
encoding ?: BufferEncoding
14
- stdioString ?: boolean
17
+ stdioString ?: boolean | undefined
15
18
} & BuiltinForkOptions
16
19
17
20
export type ForkResult < Output , Extra > = Promise <
@@ -25,6 +28,47 @@ export type ForkResult<Output, Extra> = Promise<
25
28
} & Extra
26
29
> & { process : BuiltinForkResult ; stdio : BuiltinForkResult [ 'stdio' ] }
27
30
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
+
28
72
export function fork < O extends ForkOptions > (
29
73
cmd : string ,
30
74
args : string [ ] ,
@@ -57,8 +101,7 @@ export function fork<O extends ForkOptions>(
57
101
cmd,
58
102
args,
59
103
...result ,
60
- stdout : Buffer . concat ( stdout ) . toString ( encoding ) ,
61
- stderr : Buffer . concat ( stderr ) . toString ( encoding ) ,
104
+ ...stdioResult ( stdout , stderr , builtinForkOptions ) ,
62
105
...extra
63
106
} )
64
107
@@ -68,20 +111,16 @@ export function fork<O extends ForkOptions>(
68
111
}
69
112
70
113
const proc = builtinFork ( cmd , args , builtinForkOptions )
71
- . on ( 'error' , error => rejectWithOpts ( error , { } ) )
114
+ . on ( 'error' , rejectWithOpts )
72
115
. on ( 'close' , ( code , signal ) => {
73
- if ( code !== 0 || signal ) {
116
+ if ( code || signal ) {
74
117
rejectWithOpts ( closeError , { code, signal } )
75
118
} else {
76
119
resolve ?.( getResult ( { code, signal } ) )
77
120
}
78
121
} )
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 )
85
124
; ( promise as any ) . stdin = proc . stdin
86
125
; ( promise as any ) . process = proc
87
126
return promise
0 commit comments