import * as chalk from 'chalk' ; import * as inquirer from 'inquirer' ; import * as ProgressBar from 'progress' ; import { table } from 'table' ; import { formatString } from './format' ; inquirer . registerPrompt ( 'autocomplete' , require ( 'inquirer-autocomplete-prompt' ) ) ; class Logger { private prefixLength = 5 ; private verbose = false ; public debug ( message ) { if ( ! this . verbose ) { return ; } const prefix = chalk . cyan ( this . padPrefix ( 'debug' ) ) ; console . log ( this . prefixMessage ( prefix , message ) ) ; } public info ( message ) { const prefix = chalk . blue ( this . padPrefix ( 'info' ) ) ; console . log ( this . prefixMessage ( prefix , message ) ) ; } public warn ( message ) { const prefix = chalk . yellow ( this . padPrefix ( 'warn' ) ) ; console . log ( this . prefixMessage ( prefix , message ) ) ; } public error ( message ) { const prefix = chalk . red ( this . padPrefix ( 'error' ) ) ; console . error ( this . prefixMessage ( prefix , message ) ) ; } public progress ( total = 100 ) { const prefix = this . padPrefix ( '' ) ; const bar = new ProgressBar ( `${ prefix }[:bar] :percent` , { complete : '=' , incomplete : ' ' , width : 50 , total , } ) ; bar . update ( 0.0 ) ; return bar ; } public table ( rows ) { const options = { drawHorizontalLine : ( index , size ) : boolean => { return index === 0 || index === 1 || index === size ; } , } ; this . info ( table ( rows , options ) ) ; } public askBoolean ( message , defaultValue ) { return this . promptInquirer ( 'confirm' , { message , default : defaultValue , } ) ; } public askInput ( message , defaultValue ? ) { return this . promptInquirer ( 'input' , { message , default : defaultValue , validate : ( input ) => { if ( input . trim ( ) . length === 0 ) { return 'Input cannot be blank' ; } return true ; } , } ) ; } public askPassword ( message ) { return this . promptInquirer ( 'password' , { message , validate : ( input ) => { if ( input . trim ( ) . length === 0 ) { return 'Input cannot be blank' ; } return true ; } , } ) ; } public async askAutocomplete < T > ( message , options ) { const labels = options . map ( option => option [ 1 ] ) ; const selectedLabel = await this . promptInquirer ( 'autocomplete' , { message , source : async ( answersSoFar , input ) => { if ( input === undefined ) { return labels ; } input = input . toLowerCase ( ) ; return labels . filter ( label => label . toLowerCase ( ) . includes ( input ) ) ; } , } ) ; return options . find ( option => option [ 1 ] === selectedLabel ) [ 0 ] ; } public isVerbose ( ) { return this . verbose ; } public enableVerboseMessages ( ) { this . verbose = true ; } private async promptInquirer ( type , options ) { const { answer } = await inquirer . prompt ( [ { ... options , type , name : 'answer' , prefix : chalk . magenta ( this . padPrefix ( 'input' ) . trimRight ( ) ) , } , ] ) ; return answer ; } private padPrefix ( prefix ) { return ' ' . repeat ( this . prefixLength - prefix . length ) + prefix + ' ' ; } private prefixMessage ( prefix , message ) { return formatString ( message ) . toString ( ) . split ( '\n' ) . map ( line => prefix + line ) . join ( '\n' ) ; } } export const logger = new Logger ( ) ;