import * as fs from "fs" ; import { IImperativeError , Logger , TextUtils } from "@zowe/imperative" ; const stringWidth = require ( "string-width" ) ; param { string } str param { number } len param { string } padChar return { string } export function padLeft ( str , len , padChar = " " ) { if ( str . length >= len ) { return str ; } if ( padChar . length > 1 ) { throw new Error ( "Specify only one character" ) ; } if ( padChar . length === 0 ) { throw new Error ( "Specify at least one character" ) ; } return padChar . repeat ( len - str . length ) + str ; } param { string } str return { string } export function trimLineToTerminalWidth ( str ) { const terminalWidth = process . stdout . columns - 1 ; const ellipsisLength = 3 ; str = str . replace ( /\t/g , " " ) ; if ( stringWidth ( str ) < terminalWidth || stringWidth ( str ) <= ellipsisLength ) { return str ; } return `${ str . slice ( 0 , - 1 * ( stringWidth ( str ) - terminalWidth + ellipsisLength ) ) }...` ; } param { string | string [ ] } content param { number } lineIndex return { string } export function getErrorContext ( content , lineIndex ) { let retValue = "" ; if ( lineIndex < 0 ) { return retValue ; } let lines = content ; if ( typeof content === "string" ) { if ( fs . existsSync ( content ) ) { lines = fs . readFileSync ( content ) . toString ( ) . split ( /\r?\n/ ) ; } else { throw new Error ( `File ${ content } not found!` ) ; } } const maxLineIndexLength = Math . max ( ( lineIndex + 1 ) . toString ( ) . length , ( lineIndex + 2 ) . toString ( ) . length ) ; if ( lineIndex > 0 ) { retValue += trimLineToTerminalWidth ( `\n   ${ padLeft ( lineIndex . toString ( ) , maxLineIndexLength ) } |  ${ lines [ lineIndex - 1 ] }` ) ; } retValue += trimLineToTerminalWidth ( `\n > ${ TextUtils . chalk . red ( padLeft ( ( lineIndex + 1 ) . toString ( ) , maxLineIndexLength ) ) } |  ${ lines [ lineIndex ] }` ) ; if ( lineIndex + 1 < lines . length ) { retValue += trimLineToTerminalWidth ( `\n   ${ padLeft ( ( lineIndex + 2 ) . toString ( ) , maxLineIndexLength ) } |  ${ lines [ lineIndex + 1 ] }` ) ; } return retValue ; } param { number } ms returns { Promise < void > } example export function sleep ( ms = 1000 ) { return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ; } /**
 * Utility function to read complete standard in contents from a handler
 * Can be awaited from async methods
 */ export function readStdin ( ) { return new Promise < Buffer > ( ( resolve , reject ) => { let stdinContent = Buffer . from ( [ ] ) ; const stream = process . stdin ; const log = Logger . getAppLogger ( ) ; stream . resume ( ) ; stream . on ( "data" , ( chunk ) => { log . trace ( `Read data from stdin: ${ chunk . toString ( ) }` ) ; log . debug ( `Read ${ chunk . length } bytes of data from stdin` ) ; stdinContent = Buffer . concat ( [ stdinContent , chunk ] ) ; } ) ; stream . once ( "end" , ( ) => { log . info ( "Finished reading stdin" ) ; resolve ( stdinContent ) ; } ) ; stream . on ( "error" , ( error ) => { const stdinReadError = { msg : "Error encountered while reading from stdin" , causeErrors : error , additionalDetails : ( error == null ) ? undefined : error . message } ; reject ( stdinReadError ) ; } ) ; } ) ; } param poolLimit param array param iteratorFn export function asyncPool ( poolLimit , array , iteratorFn ) { let i = 0 ; const ret = [ ] ; const executing = [ ] ; const enqueue = ( ) => { if ( i === array . length ) { return Promise . resolve ( ) ; } const item = array [ i ++ ] ; const p = Promise . resolve ( ) . then ( ( ) => iteratorFn ( item , array ) ) ; ret . push ( p ) ; const e = p . then ( ( ) => executing . splice ( executing . indexOf ( e ) , 1 ) ) ; executing . push ( e ) ; let r = Promise . resolve ( ) ; if ( executing . length >= poolLimit ) { r = Promise . race ( executing ) ; } return r . then ( ( ) => enqueue ( ) ) ; } ; return enqueue ( ) . then ( ( ) => Promise . all ( ret ) ) ; }