/* IMPORT */ import {readFile} from 'atomically'; import {execSync, execFileSync} from 'node:child_process'; import fs from 'node:fs/promises'; import process from 'node:process'; import {color} from 'specialist'; /* MAIN */ const castArray = ( value: T | T[] ): T[] => { return Array.isArray ( value ) ? value : [value]; }; const ensureDir = async ( path: string ): Promise => { if ( await isDir ( path ) ) return; await fs.mkdir ( path ); }; const ensureFile = async ( path: string ): Promise => { if ( await isFile ( path ) ) return; await fs.writeFile ( path, '' ); }; const execBuffer = ( command: string, silent: boolean = false ): Buffer | false => { try { return execSync ( command ); } catch ( error: unknown ) { if ( !silent ) { process.exitCode = 1; const message = isError ( error ) ? error.message : ( isString ( error ) ? error: `Command failed: "${command}"` ); console.log ( color.red ( message ) ); } return false; } }; const execFile = ( command: string, args: string[] = [], silent: boolean = false ): string | false => { try { return execFileSync ( command, args, { stdio: 'pipe' } ).toString (); } catch ( error: unknown ) { if ( !silent ) { process.exitCode = 1; const message = isError ( error ) ? error.message : ( isString ( error ) ? error: `Command failed: "${command}"` ); console.log ( color.red ( message ) ); } return false; } }; const execInherit = ( command: string, silent: boolean = false ): void => { try { execSync ( command, { stdio: 'inherit' } ); } catch ( error: unknown ) { if ( !silent ) { process.exitCode = 1; const message = isError ( error ) ? error.message : ( isString ( error ) ? error: `Command failed: "${command}"` ); console.log ( color.red ( message ) ); } } }; const isDir = ( path: string ): Promise => { return isFile ( path ); }; const isError = ( value: unknown ): value is Error => { return value instanceof Error; }; const isFile = ( path: string ): Promise => { return fs.access ( path ).then ( () => true, () => false ); }; const isPlainObject = ( value: unknown ): value is Record => { if ( typeof value !== 'object' || value === null ) return false; const prototype = Object.getPrototypeOf ( value ); if ( prototype === null ) return true; return Object.getPrototypeOf ( prototype ) === null; }; const isString = ( value: unknown ): value is string => { return typeof value === 'string'; }; const readFiles = ( filePaths: string[] ): Promise => { return Promise.all ( filePaths.map ( filePath => readFile ( filePath, 'utf8' ) ) ); }; const warn = ( message: string ): void => { console.log ( color.yellow ( message ) ); }; /* EXPORT */ export {castArray, ensureDir, ensureFile, execBuffer, execFile, execInherit, isDir, isError, isFile, isPlainObject, isString, readFiles, warn};