import { WriteStream } from "tty" ; import progressBar from "cli-progress" ; import { createLogFormatter , LogFormatter } from "./formatter" ; import { AutorestSyncLogger } from "./logger" ; import { LoggerSink , LogInfo , Progress , ProgressTracker } from "./types" ; export interface ConsoleLoggerSinkOptions { /**
     * Stream to use for output. (@default stdout)
     */ stream ? : NodeJS . WritableStream ; format ? : "json" | "regular" ; color ? : boolean ; timestamp ? : boolean ; /**
     * Enable output for non TTY output(e.g. file) for the progress file.
     */ progressNoTTYOutput ? : boolean ; } /**
 * Logger sink to output logs to the console.
 */ export class ConsoleLoggerSink implements LoggerSink { private formatter : LogFormatter ; private currentProgressBar : progressBar . MultiBar | undefined ; private bars : progressBar . SingleBar [ ] = [ ] ; private pendingLogs : string [ ] = [ ] ; private format : "json" | "regular" ; private stream : NodeJS . WritableStream ; public constructor ( private options = { } ) { this . stream = options . stream ?? process . stdout ; this . format = options . format ?? "regular" ; this . formatter = createLogFormatter ( options . format , options ) ; } public log ( log ) { const line = this . formatter . log ( log ) ; if ( this . currentProgressBar ) { this . pendingLogs . push ( line ) ; } else { this . writeLine ( line ) ; } } public startProgress ( initialName ? ) { if ( this . format === "regular" ) { return this . startProgressBar ( initialName ) ; } else { return NoopProgress ; } } private startProgressBar ( initialName ? ) { if ( this . currentProgressBar === undefined ) { this . currentProgressBar = new progressBar . MultiBar ( { hideCursor : true , stream : this . stream , noTTYOutput : this . options . progressNoTTYOutput , format : "{name} [{bar}] {percentage}% | {value}/{total}" , forceRedraw : true , } , progressBar . Presets . legacy ) ; } const multiBar = this . currentProgressBar ; multiBar . on ( "redraw-pre" , ( ) => { if ( this . pendingLogs . length > 0 ) { if ( "clearLine" in this . stream ) { ( this . stream as WriteStream ) . clearLine ( 1 ) ; } } while ( this . pendingLogs . length > 0 ) { this . writeLine ( this . pendingLogs . shift ( ) ) ; } } ) ; multiBar . on ( "stop" , ( ) => { this . currentProgressBar = undefined ; while ( this . pendingLogs . length > 0 ) { this . writeLine ( this . pendingLogs . shift ( ) ) ; } } ) ; let bar ; const update = ( progress ) => { const name = progress . name ?? initialName ?? "progress" ; if ( bar === undefined ) { bar = multiBar . create ( progress . total , 0 , { name } ) ; this . bars . push ( bar ) ; } else { bar . setTotal ( progress . total ) ; } bar . update ( progress . current , { name } ) ; } ; const stop = ( ) => { if ( bar ) { bar . update ( bar . getTotal ( ) ) ; bar . render ( ) ; bar . stop ( ) ; multiBar . remove ( bar ) ; this . bars = this . bars . filter ( ( x ) => x !== bar ) ; if ( this . bars . length === 0 ) { multiBar . stop ( ) ; this . currentProgressBar = undefined ; } } } ; return { update , stop , } ; } private writeLine ( line ) { if ( line !== undefined ) { this . stream . write ( Buffer . from ( `${ line }\n` ) ) ; } } } /**
 * Simple logger which takes log info as it is and logs it.
 * Doesn't resolve original source locations.
 */ export class ConsoleLogger extends AutorestSyncLogger { public constructor ( options = { } ) { super ( { sinks : [ new ConsoleLoggerSink ( options ) ] } ) ; } } const NoopProgress = { update : ( ) => null , stop : ( ) => null , } ;