1
1
import path from 'node:path'
2
2
import process from 'node:process'
3
3
4
- import { fork } from './promise-fork'
4
+ import spawn from '@npmcli/promise-spawn'
5
+
6
+ import { isObject } from '@socketsecurity/registry/lib/objects'
7
+
5
8
import constants from '../constants'
6
9
7
- import type { ForkOptions , ForkResult } from './promise-fork'
8
- import type { Serializable } from 'node:child_process'
10
+ type SpawnOption = Exclude < Parameters < typeof spawn > [ 2 ] , undefined >
9
11
10
12
const { abortSignal } = constants
11
13
12
- type ShadowNpmInstallOptions = ForkOptions & {
14
+ type ShadowNpmInstallOptions = SpawnOption & {
13
15
flags ?: string [ ]
14
- ipc ?: Serializable
16
+ ipc ?: object
15
17
}
16
18
17
- export function shadowNpmInstall < O extends ShadowNpmInstallOptions > (
18
- opts ?: ShadowNpmInstallOptions
19
- ) {
20
- const { flags = [ ] , ipc, ...forkOptions } = { __proto__ : null , ...opts }
19
+ export function shadowNpmInstall ( opts ?: ShadowNpmInstallOptions ) {
20
+ const { flags = [ ] , ipc, ...spawnOptions } = { __proto__ : null , ...opts }
21
+ const useIpc = isObject ( ipc )
21
22
// Lazily access constants.ENV.
22
23
const { SOCKET_CLI_DEBUG } = constants . ENV
23
- const promise = fork (
24
- // Lazily access constants.rootBinPath .
25
- path . join ( constants . rootBinPath , 'npm-cli.js' ) ,
24
+ const promise = spawn (
25
+ // Lazily access constants.execPath .
26
+ constants . execPath ,
26
27
[
28
+ // Lazily access constants.rootBinPath.
29
+ path . join ( constants . rootBinPath , 'npm-cli.js' ) ,
27
30
'install' ,
28
31
// Even though the 'silent' flag is passed npm will still run through code
29
32
// paths for 'audit' and 'fund' unless '--no-audit' and '--no-fund' flags
@@ -35,16 +38,26 @@ export function shadowNpmInstall<O extends ShadowNpmInstallOptions>(
35
38
] ,
36
39
{
37
40
signal : abortSignal ,
38
- // Lazily access constants.ENV.
39
- stdio : SOCKET_CLI_DEBUG ? 'inherit' : 'ignore' ,
40
- ...forkOptions ,
41
+ // Set stdio to include 'ipc'.
42
+ // See https://github.com/nodejs/node/blob/v23.6.0/lib/child_process.js#L161-L166
43
+ // and https://github.com/nodejs/node/blob/v23.6.0/lib/internal/child_process.js#L238.
44
+ stdio : SOCKET_CLI_DEBUG
45
+ ? // 'inherit'
46
+ useIpc
47
+ ? [ 0 , 1 , 2 , 'ipc' ]
48
+ : 'inherit'
49
+ : // 'ignore'
50
+ useIpc
51
+ ? [ 'ignore' , 'ignore' , 'ignore' , 'ipc' ]
52
+ : 'ignore' ,
53
+ ...spawnOptions ,
41
54
env : {
42
55
...process . env ,
43
- ...forkOptions . env
56
+ ...spawnOptions . env
44
57
}
45
58
}
46
- ) as ForkResult < O extends { stdioString : false } ? Buffer : string , undefined >
47
- if ( ipc ) {
59
+ )
60
+ if ( useIpc ) {
48
61
promise . process . send ( ipc )
49
62
}
50
63
return promise
0 commit comments