import { createHandle , Handle } from '@theintern/common' ; import { mkdirSync , statSync , writeFile as fsWriteFile } from 'fs' ; import { dirname } from 'path' ; import { execSync } from 'child_process' ; param emitter param event param listener returns export function on ( emitter , event , listener ) { emitter . on ( event , listener ) ; return createHandle ( ( ) => emitter . removeListener ( event , listener ) ) ; } param filename returns export function fileExists ( filename ) { try { statSync ( filename ) ; return true ; } catch ( error ) { return false ; } } /**
 * Kill a process and its immediate children
 *
 * This function will attempt to kill all processes that it should, and will
 * report an error at the end if any process could not be killed.
 */ export function kill ( pid ) { let error ; if ( pid === undefined ) { return ; } getChildProcesses ( pid ) . forEach ( ( childPid ) => { try { killProcess ( childPid ) ; } catch ( err ) { error = err ; } } ) ; try { killProcess ( pid ) ; } catch ( err ) { error = err ; } if ( error ) { throw new Error ( `Failed to kill ${ pid } or one of its children: ${ error . message }` ) ; } } function killProcess ( pid ) { try { process . kill ( pid ) ; } catch ( error ) { if ( error . code !== 'ESRCH' ) { throw error ; } } } param data param filename returns export function writeFile ( data , filename ) { return new Promise < void > ( function ( resolve , reject ) { function mkdirp ( dir ) { if ( ! dir ) { return ; } try { mkdirSync ( dir ) ; } catch ( error ) { if ( error . code === 'ENOENT' ) { mkdirp ( dirname ( dir ) ) ; mkdirp ( dir ) ; } else { if ( ! statSync ( dir ) . isDirectory ( ) ) { throw error ; } } } } mkdirp ( dirname ( filename ) ) ; fsWriteFile ( filename , data , function ( error ) { if ( error ) { reject ( error ) ; } else { resolve ( ) ; } } ) ; } ) ; } /**
 * Get the children of a process
 */ function getChildProcesses ( pid ) { const command = process . platform === 'win32' ? 'wmic PROCESS GET ParentProcessId,ProcessId' : 'ps -A -o ppid,pid' ; return execSync ( command , { encoding : 'utf8' } ) . trim ( ) . split ( '\n' ) . slice ( 1 ) . map ( ( line ) => line . trim ( ) ) . map ( ( line ) => line . split ( /\s+/ ) . map ( ( word ) => word . trim ( ) ) ) . map ( ( words ) => ( { parent : Number ( words [ 0 ] ) , child : Number ( words [ 1 ] ) } ) ) . filter ( ( entry ) => entry . parent === pid ) . map ( ( entry ) => entry . child ) ; }