44// Copyright (c) npm, Inc.
55import { 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
912type BuiltinForkResult = ReturnType < typeof builtinFork >
1013
1114export type ForkOptions = {
1215 cwd ?: string
1316 encoding ?: BufferEncoding
14- stdioString ?: boolean
17+ stdioString ?: boolean | undefined
1518} & BuiltinForkOptions
1619
1720export 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+
2872export 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