packageDocumentation module import { execFileSync , spawn } from "child_process" ; import { EventEmitter } from "events" ; import * as fs from "fs" ; import * as semver from "semver" ; internal export type MD5Options = "NoCheck" | "LogOnly" | "FailIfDifferent" | "FailIfDifferentOrMissing" ; internal export type LogLevel = "INFO" | "WARNING" | "ERROR" ; internal export interface CopyOptions { blobType ? : string ; blockBlobTier ? : string ; blockSizeMb ? : number ; checkMD5 ? : MD5Options ; contentEncoding ? : string ; contentType ? : string ; followSymLinks ? : boolean ; logLevel ? : LogLevel ; noGuessMimeType ? : boolean ; preserveLastModifiedTime ? : boolean ; putMD5 ? : boolean ; recursive ? : boolean ; overwrite ? : boolean ; } internal export interface Configuration { concurrencyValue ? : number ; logLocation ? : string ; showPerfStates ? : boolean ; pacePageBlobs ? : boolean ; defaultServiceApiVersion ? : string ; } internal export type MessageType = "Init" | "Info" | "Progress" | "Exit" | "Error" | "Prompt" ; internal export interface MessageEventArgs { TimeStamp : string ; MessageType : MessageType ; } internal export interface StringEventArgs extends MessageEventArgs { MessageContent : string ; } internal export interface InitEventArgs extends MessageEventArgs { LogFileLocation : string ; JobID : string ; } internal export interface ProgressEventArgs extends MessageEventArgs { ErrorMsg : string ; ActiveConnections : number ; CompleteJobOrdered : boolean ; JobStatus : string ; TotalTransfers : number ; TransfersCompleted : number ; TransfersFailed : number ; TransfersSkipped : number ; BytesOverWire : number ; TotalBytesTransferred : number ; TotalBytesEnumerated : number ; FailedTransfers : any [ ] ; SkippedTransfers ? : any ; PerfConstraint : number ; } internal export declare interface AzCopy { on ( event , listener ) : this ; on ( event , listener ) : this ; on ( event , listener ) : this ; on ( event , listener ) : this ; } internal export class AzCopy extends EventEmitter { private static _resolvedExecPath ? : string ; private static _minimumAzCopyVersionSupported = "10.1.0" ; private static _currentAzCopyVersion ? : string ; /** Attempt to initialize azcopy utility class */ private static init ( ) { const currentVersion = this . getVersion ( ) ; if ( ! semver . gte ( currentVersion , AzCopy . _minimumAzCopyVersionSupported ) ) throw new Error ( `AzCopy version ${ currentVersion } must be >= ${ AzCopy . _minimumAzCopyVersionSupported }` ) ; } param config public constructor ( public config = { } ) { super ( ) ; } /** check if azcopy has been configured and also initialize it. */ public static get isAvailable ( ) : boolean { try { this . init ( ) ; return true ; } catch { return false ; } } /** Return path to azopy image if configured */ public static get execPath ( ) : string { if ( ! AzCopy . _resolvedExecPath ) { if ( ! process . env . AZCOPY_BINARY_PATH ) { throw new Error ( `AZCOPY_BINARY_PATH is not set` ) ; } if ( ! fs . existsSync ( process . env . AZCOPY_BINARY_PATH ) ) { throw new Error ( `AzCopy binary '${ process . env . AZCOPY_BINARY_PATH }' does not exist.` ) ; } AzCopy . _resolvedExecPath = process . env . AZCOPY_BINARY_PATH ; } return AzCopy . _resolvedExecPath ; } /** Return binary version of configured azcopy */ public static getVersion ( ) { if ( ! AzCopy . _currentAzCopyVersion ) { const cmd = execFileSync ( AzCopy . execPath , [ "--version" ] , { encoding : "utf8" } ) ; const match = cmd . match ( /[0-9]+\.[0-9]+\.[0-9]+/ ) ; if ( match ) AzCopy . _currentAzCopyVersion = match [ 0 ] ; else AzCopy . _currentAzCopyVersion = "" ; } return AzCopy . _currentAzCopyVersion ; } param source param dest param options public async copy ( source , dest , options ? ) { AzCopy . init ( ) ; const args = [ "copy" , `${ source }` , `${ dest }` , "--output-type=json" ] ; if ( options ) { if ( options . blobType ) args . push ( `--blob-type=${ options . blobType }` ) ; if ( options . blockBlobTier ) args . push ( `--block-blob-tier=${ options . blockBlobTier }` ) ; if ( options . blockSizeMb ) args . push ( `--block-size-mb=${ options . blockSizeMb }` ) ; if ( options . checkMD5 ) args . push ( `--check-md5=${ options . checkMD5 }` ) ; if ( options . contentEncoding ) args . push ( `--content-encoding=${ options . contentEncoding }` ) ; if ( options . contentType ) args . push ( `--content-type=${ options . contentType }` ) ; if ( options . followSymLinks ) args . push ( `--follow-symlinks=${ options . followSymLinks }` ) ; if ( options . logLevel ) args . push ( `--log-level=${ options . logLevel }` ) ; if ( options . noGuessMimeType ) args . push ( `--no-guess-mime-type=${ options . noGuessMimeType }` ) ; if ( options . preserveLastModifiedTime ) args . push ( `--preserve-last-modified-time=${ options . preserveLastModifiedTime }` ) ; if ( options . putMD5 ) args . push ( `--put-md5=${ options . putMD5 }` ) ; if ( options . recursive ) args . push ( `--recursive=${ options . recursive }` ) ; if ( options . overwrite ) args . push ( `--overwrite=${ options . overwrite }` ) ; } const azenv = { ... process . env } ; if ( this . config . concurrencyValue ) { Object . defineProperty ( azenv , "AZCOPY_CONCURRENCY_VALUE" , { value : this . config . concurrencyValue . toString ( ) , enumerable : true } ) ; } if ( this . config . logLocation ) { Object . defineProperty ( azenv , "AZCOPY_LOG_LOCATION" , { value : this . config . logLocation , enumerable : true } ) ; } if ( this . config . showPerfStates ) { Object . defineProperty ( azenv , "AZCOPY_SHOW_PERF_STATES" , { value : this . config . showPerfStates , enumerable : true } ) ; } if ( this . config . pacePageBlobs ) { Object . defineProperty ( azenv , "AZCOPY_PACE_PAGE_BLOBS" , { value : this . config . pacePageBlobs . toString ( ) , enumerable : true } ) ; } if ( this . config . defaultServiceApiVersion ) { Object . defineProperty ( azenv , "AZCOPY_DEFAULT_SERVICE_API_VERSION" , { value : this . config . defaultServiceApiVersion , enumerable : true } ) ; } const enableEvents = this . listenerCount ( "azinit" ) || this . listenerCount ( "azinfo" ) || this . listenerCount ( "azprogress" ) || this . listenerCount ( "azexit" ) || this . listenerCount ( "azerror" ) ; return new Promise < number > ( ( resolve , reject ) => { const cmd = spawn ( AzCopy . execPath , args , { cwd : process . cwd ( ) , env : azenv , stdio : "pipe" } ) ; cmd . stdout . setEncoding ( "utf8" ) ; cmd . stderr . setEncoding ( "utf8" ) ; if ( enableEvents ) { cmd . stdout . on ( "data" , ( data ) => { for ( const m of data . split ( "\n" ) ) { if ( m . length === 0 ) continue ; const msg = JSON . parse ( m ) ; const eventId = `az${ ( msg . MessageType as string ) . toLowerCase ( ) }` ; if ( msg . MessageType === "Progress" || msg . MessageType === "Exit" ) { this . emit ( eventId , { TimeStamp : msg . TimeStamp , MessageType : msg . MessageType , ... JSON . parse ( msg . MessageContent ) } ) ; } else if ( msg . MessageType === "Init" ) { this . emit ( eventId , { TimeStamp : msg . TimeStamp , MessageType : msg . MessageType , ... JSON . parse ( msg . MessageContent ) } ) ; } else { this . emit ( eventId , { TimeStamp : msg . TimeStamp , MessageType : msg . MessageType , MessageContent : msg . MessageContent } ) ; } } } ) ; } cmd . stderr . on ( "data" , ( data ) => { this . emit ( "azruntimeerror" , data ) ; } ) ; cmd . on ( "exit" , ( code ) => { resolve ( code ) ; } ) ; cmd . on ( "close" , ( code ) => { resolve ( code ) ; } ) ; cmd . on ( "error" , ( code , _signal ) => { reject ( code ) ; } ) ; } ) ; } }