import { createWriteStream } from 'fs' ; import { emitKeypressEvents } from 'readline' ; import builtinModules from 'builtin-modules' ; import readPkgUp from 'read-pkg-up' ; import * as t from 'io-ts' ; import { zip } from 'lodash' ; import { KeypressDetails } from './prompt' ; const { env } = process ; export interface LooseObject { [ key ] : any ; } const debugFifo = env . JAY_FIFO === undefined && env . JAY_DEBUG === undefined ? null : createWriteStream ( env . JAY_FIFO || 'jay-debug' ) ; export const debug = ( msg , ... rest ) : any => debugFifo && msg . startsWith ( env . JAY_DEBUG || '' ) && debugFifo . write ( [ msg ] . concat ( rest ) . join ( ' ' ) + '\n' ) ; export const time = ( title ) : ( ( ) => string ) => { const [ , start ] = process . hrtime ( ) ; return ( ) => `time ${ title }: ${ ( process . hrtime ( ) [ 1 ] - start ) / 1e6 }ms` ; } ; export function getColumnSizes ( input ) { return input . reduce ( ( sizes , row ) => zip ( sizes , row ) . map ( ( [ size , cell ] ) => Math . max ( ( cell || '' ) . length , size || 0 ) ) , [ ] as number [ ] ) ; } export function returnError < T > ( fn ) { try { return fn ( ) ; } catch ( error ) { return error ; } } export function getKeyPress ( stream ) { return new Promise ( resolve => { if ( ! stream . isTTY || ! stream . setRawMode ) { return false ; } const setRawMode = ( b ) => stream . setRawMode && stream . setRawMode ( b ) ; const wasRaw = stream . isRaw || false ; setRawMode ( true ) ; stream . resume ( ) ; emitKeypressEvents ( stream ) ; stream . once ( 'keypress' , ( key , details ) => { setRawMode ( wasRaw ) ; resolve ( details ) ; stream . pause ( ) ; } ) ; } ) ; } export const addBuiltinsToObject = ( o ) : void => builtinModules . forEach ( m => Object . defineProperty ( o , m , { configurable : true , enumerable : false , get ( ) { const required = require ( m ) ; delete o [ m ] ; Object . defineProperty ( o , m , { configurable : true , enumerable : false , writable : true , value : required } ) ; return required ; } } ) ) ; export const packageJson = t . intersection ( [ t . type ( { name : t . string , version : t . string , description : t . string , homepage : t . string , author : t . type ( { name : t . string , email : t . string , url : t . string } ) } ) , t . record ( t . string , t . unknown ) ] ) . decode ( ( readPkgUp . sync ( { cwd : __dirname } ) || { package : { } } ) . package ) . getOrElseL ( ( ) => { throw new Error ( 'Couldn\'t parse `package.json` - invalid format' ) ; } ) ;