import { ChildProcess } from 'child_process' ; import * as fs from 'fs' ; import * as path from 'path' ; namespace ProcessUtil { param child param wait export const kill = ( child , wait = 500 ) : Promise < void > => { return new Promise < void > ( ( resolve , reject ) => { try { if ( child . stdin !== null ) { child . stdin . end ( ) ; } if ( child . stdout !== null ) { child . stdout . unpipe ( ) ; child . stdout . destroy ( ) ; child . stdout . removeAllListeners ( 'data' ) ; } if ( child . stderr !== null ) { child . stderr . unpipe ( ) ; child . stderr . destroy ( ) ; child . stderr . removeAllListeners ( 'data' ) ; } setTimeout ( ( ) => { child . kill ( 'SIGINT' ) ; resolve ( ) ; } , wait ) ; } catch ( err ) { reject ( err ) ; } } ) ; } ; export interface Cmds { bin : string ; args : string [ ] ; } export const ROOT_PATH = path . join ( __dirname , '..' , '..' ) . replace ( new RegExp ( `\\${ path . sep }$` ) , '' ) ; param cmd return export const parseCmdStr = ( cmd ) : ProcessUtil . Cmds => { let args = cmd . split ( ' ' ) ; let bin = args . shift ( ) ; if ( typeof bin === 'undefined' ) { throw new Error ( 'CmdParseError' ) ; } bin = bin . replace ( /%NODE%/g , process . argv [ 0 ] ) ; try { fs . statSync ( bin ) ; } catch ( e ) { throw new Error ( 'CmdBinIsNotFound' ) ; } args = args . map ( arg => { return arg . replace ( /%ROOT%/g , ROOT_PATH ) ; } ) . map ( arg => { return arg . replace ( /%SPACE%/g , ' ' ) ; } ) ; return { bin : bin , args : args . filter ( arg => { return arg . length > 0 ; } ) , } ; } ; param child return export const isExited = ( child ) : boolean => { return child . exitCode !== null ; } ; } export default ProcessUtil ;