2023-03-19 15:37:07 +00:00
import * as execa from 'execa' ;
import commandToString from './commandToString' ;
import splitCommandString from './splitCommandString' ;
import { stdout } from 'process' ;
interface ExecCommandOptions {
showInput? : boolean ;
showStdout? : boolean ;
showStderr? : boolean ;
quiet? : boolean ;
2024-04-05 12:16:49 +01:00
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
2023-10-30 11:32:14 +00:00
env? : Record < string , any > ;
2025-03-16 10:18:32 +00:00
detached? : boolean ;
2023-03-19 15:37:07 +00:00
}
export default async ( command : string | string [ ] , options : ExecCommandOptions | null = null ) : Promise < string > = > {
2025-04-09 08:14:17 +01:00
const detached = options ? options.detached : false ;
// When launching a detached executable it's better not to pipe the stdout and stderr, as this
// will most likely cause an EPIPE error.
2023-03-19 15:37:07 +00:00
options = {
2025-04-09 08:14:17 +01:00
showInput : ! detached ,
showStdout : ! detached ,
showStderr : ! detached ,
2023-03-19 15:37:07 +00:00
quiet : false ,
2023-10-30 11:32:14 +00:00
env : { } ,
2023-03-19 15:37:07 +00:00
. . . options ,
} ;
if ( options . quiet ) {
options . showInput = false ;
options . showStdout = false ;
options . showStderr = false ;
}
if ( options . showInput ) {
if ( typeof command === 'string' ) {
stdout . write ( ` > ${ command } \ n ` ) ;
} else {
stdout . write ( ` > ${ commandToString ( command [ 0 ] , command . slice ( 1 ) ) } \ n ` ) ;
}
}
const args : string [ ] = typeof command === 'string' ? splitCommandString ( command ) : command as string [ ] ;
const executableName = args [ 0 ] ;
args . splice ( 0 , 1 ) ;
2025-05-19 15:02:18 -07:00
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Workaround for type definition conflicts. Expo currently overrides NodeJs.ProcessEnv, making NODE_ENV required. This changes the type of the "env" argument to execa.
const promise = execa ( executableName , args , { env : options.env as any } ) ;
2023-03-19 15:37:07 +00:00
if ( options . showStdout && promise . stdout ) promise . stdout . pipe ( process . stdout ) ;
2023-04-06 12:11:45 +02:00
if ( options . showStderr && promise . stderr ) promise . stderr . pipe ( process . stderr ) ;
2023-03-19 15:37:07 +00:00
const result = await promise ;
return result . stdout . trim ( ) ;
} ;