import { AbstractSession , ImperativeError , ImperativeExpect , IO , ITaskWithStatus , Logger , TaskProgress } from "@zowe/imperative" ; import * as fs from "fs" ; import * as path from "path" ; import { IHeaderContent , ZosmfHeaders , ZosmfRestClient , asyncPool } from "@zowe/core-for-zowe-sdk" ; import { ZosFilesConstants } from "../../constants/ZosFiles.constants" ; import { ZosFilesMessages } from "../../constants/ZosFiles.messages" ; import { IZosFilesResponse } from "../../doc/IZosFilesResponse" ; import { ZosFilesUtils } from "../../utils/ZosFilesUtils" ; import { List } from "../list" ; import { IUploadOptions } from "./doc/IUploadOptions" ; import { IUploadResult } from "./doc/IUploadResult" ; import { Create } from "../create" ; import { IUploadFile } from "./doc/IUploadFile" ; import { IUploadDir } from "./doc/IUploadDir" ; import { ZosFilesAttributes , TransferMode } from "../../utils/ZosFilesAttributes" ; import { Utilities , Tag } from "../utilities" ; import { Readable } from "stream" ; import { IOptionsFullResponse } from "../../doc/IOptionsFullResponse" ; import { IRestClientResponse } from "../../doc/IRestClientResponse" ; import { CLIENT_PROPERTY } from "../../doc/types/ZosmfRestClientProperties" ; export class Upload { param { AbstractSession } session param { string } inputFile param { string } dataSetName param { IUploadOptions } options return { Promise < IZosFilesResponse > } throws public static async fileToDataset ( session , inputFile , dataSetName , options = { } ) { this . log . info ( `Uploading file ${ inputFile } to ${ dataSetName }` ) ; ImperativeExpect . toNotBeNullOrUndefined ( inputFile , ZosFilesMessages . missingInputFile . message ) ; ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; ImperativeExpect . toNotBeEqual ( dataSetName , "" , ZosFilesMessages . missingDatasetName . message ) ; const promise = new Promise ( ( resolve , reject ) => { fs . lstat ( inputFile , ( err , stats ) => { if ( err == null && stats . isFile ( ) ) { resolve ( true ) ; } else if ( err == null ) { reject ( new ImperativeError ( { msg : ZosFilesMessages . missingInputFile . message } ) ) ; } else { reject ( new ImperativeError ( { msg : ZosFilesMessages . nodeJsFsError . message , additionalDetails : err . toString ( ) , causeErrors : err } ) ) ; } } ) ; } ) ; await promise ; return this . pathToDataSet ( session , inputFile , dataSetName , options ) ; } param { AbstractSession } session param { string } inputDir param { string } dataSetName param { IUploadOptions } options return { Promise < IZosFilesResponse > } throws public static async dirToPds ( session , inputDir , dataSetName , options = { } ) { this . log . info ( `Uploading directory ${ inputDir } to ${ dataSetName }` ) ; ImperativeExpect . toNotBeNullOrUndefined ( inputDir , ZosFilesMessages . missingInputDir . message ) ; ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; ImperativeExpect . toNotBeEqual ( dataSetName , "" , ZosFilesMessages . missingDatasetName . message ) ; const promise = new Promise ( ( resolve , reject ) => { fs . lstat ( inputDir , ( err , stats ) => { if ( err == null && ! stats . isFile ( ) ) { resolve ( true ) ; } else if ( err == null ) { reject ( new ImperativeError ( { msg : ZosFilesMessages . pathIsNotDirectory . message } ) ) ; } else { reject ( new ImperativeError ( { msg : ZosFilesMessages . nodeJsFsError . message , additionalDetails : err . toString ( ) , causeErrors : err } ) ) ; } } ) ; } ) ; await promise ; if ( ! IO . isDir ( inputDir ) ) { throw new ImperativeError ( { msg : ZosFilesMessages . missingInputDir . message } ) ; } return this . pathToDataSet ( session , inputDir , dataSetName , options ) ; } param { AbstractSession } session param { Buffer } fileBuffer param { string } dataSetName param { IUploadOptions } options return { Promise < IZosFilesResponse > } throws public static async bufferToDataSet ( session , fileBuffer , dataSetName , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; let endpoint = path . posix . join ( ZosFilesConstants . RESOURCE , ZosFilesConstants . RES_DS_FILES ) ; if ( options . volume ) { endpoint = path . posix . join ( endpoint , `-(${ options . volume })` ) ; } endpoint = path . posix . join ( endpoint , dataSetName ) ; const reqHeaders = this . generateHeadersBasedOnOptions ( options ) ; if ( ! options . binary ) { fileBuffer = ZosFilesUtils . normalizeNewline ( fileBuffer ) ; } const requestOptions = { resource : endpoint , reqHeaders , writeData : fileBuffer } ; if ( options . returnEtag ) { requestOptions . dataToReturn = [ CLIENT_PROPERTY . response ] ; } const uploadRequest = await ZosmfRestClient . putExpectFullResponse ( session , requestOptions ) ; const apiResponse = { } ; if ( options . returnEtag ) { apiResponse . etag = uploadRequest . response . headers . etag ; } return { success : true , commandResponse : ZosFilesMessages . dataSetUploadedSuccessfully . message , apiResponse } ; } param { AbstractSession } session param { Buffer } fileBuffer param { string } dataSetName param { IUploadOptions } options return { Promise < IZosFilesResponse > } throws public static async streamToDataSet ( session , fileStream , dataSetName , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; let endpoint = path . posix . join ( ZosFilesConstants . RESOURCE , ZosFilesConstants . RES_DS_FILES ) ; if ( options . volume ) { endpoint = path . posix . join ( endpoint , `-(${ options . volume })` ) ; } endpoint = path . posix . join ( endpoint , dataSetName ) ; const reqHeaders = this . generateHeadersBasedOnOptions ( options ) ; const requestOptions = { resource : endpoint , reqHeaders , requestStream : fileStream , normalizeRequestNewLines : ! options . binary , task : options . task } ; if ( options . returnEtag ) { requestOptions . dataToReturn = [ CLIENT_PROPERTY . response ] ; } const uploadRequest = await ZosmfRestClient . putExpectFullResponse ( session , requestOptions ) ; const apiResponse = { } ; if ( options . returnEtag ) { apiResponse . etag = uploadRequest . response . headers . etag ; } return { success : true , commandResponse : ZosFilesMessages . dataSetUploadedSuccessfully . message , apiResponse } ; } param { AbstractSession } session param { string } inputPath param { string } dataSetName param { IUploadOptions } options param task return { Promise < IZosFilesResponse > } throws example example example example public static async pathToDataSet ( session , inputPath , dataSetName , options = { } ) { this . log . info ( `Uploading path ${ inputPath } to ${ dataSetName }` ) ; ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; ImperativeExpect . toNotBeEqual ( dataSetName , "" , ZosFilesMessages . missingDatasetName . message ) ; let memberName = "" ; let uploadingFile = "" ; let uploadingDsn = "" ; let isUploadToPds = false ; const results = [ ] ; if ( ZosFilesUtils . isDataSetNameContainMasking ( dataSetName ) ) { throw new ImperativeError ( { msg : ZosFilesMessages . unsupportedMaskingInDataSetName . message } ) ; } const uploadFileList = ZosFilesUtils . getFileListFromPath ( inputPath ) ; if ( dataSetName . endsWith ( ")" ) ) { if ( IO . isDir ( inputPath ) ) { throw new ImperativeError ( { msg : ZosFilesMessages . uploadDirectoryToDatasetMember . message } ) ; } memberName = dataSetName . substr ( dataSetName . indexOf ( "(" ) ) . replace ( /[()]/g , "" ) ; dataSetName = dataSetName . substr ( 0 , dataSetName . indexOf ( "(" ) ) ; } const listResponse = await List . dataSet ( session , dataSetName , { attributes : true , maxLength : 1 , start : dataSetName , recall : "wait" } ) ; if ( listResponse . apiResponse != null && listResponse . apiResponse . returnedRows != null && listResponse . apiResponse . items != null ) { const dsnameIndex = listResponse . apiResponse . returnedRows === 0 ? - 1 : listResponse . apiResponse . items . findIndex ( ( ds ) => ds . dsname . toUpperCase ( ) === dataSetName . toUpperCase ( ) ) ; if ( dsnameIndex !== - 1 ) { const dsInfo = listResponse . apiResponse . items [ dsnameIndex ] ; switch ( dsInfo . dsorg ) { case "PO" : case "PO-E" : isUploadToPds = true ; break ; default : if ( uploadFileList . length > 1 ) { throw new ImperativeError ( { msg : ZosFilesMessages . uploadDirectoryToPhysicalSequentialDataSet . message } ) ; } break ; } } } try { let uploadError ; let uploadsInitiated = 0 ; for ( const file of uploadFileList ) { uploadingFile = file ; uploadingDsn = dataSetName ; if ( isUploadToPds ) { if ( memberName . length === 0 ) { uploadingDsn = `${ uploadingDsn }(${ ZosFilesUtils . generateMemberName ( uploadingFile ) })` ; } else { uploadingDsn = `${ uploadingDsn }(${ memberName })` ; } } uploadingDsn = uploadingDsn . toUpperCase ( ) ; if ( options . task != null ) { const LAST_FIFTEEN_CHARS = - 15 ; const abbreviatedFile = uploadingFile . slice ( LAST_FIFTEEN_CHARS ) ; options . task . statusMessage = "Uploading ..." + abbreviatedFile ; options . task . percentComplete = Math . floor ( TaskProgress . ONE_HUNDRED_PERCENT * ( uploadsInitiated / uploadFileList . length ) ) ; uploadsInitiated ++ ; } if ( uploadError === undefined ) { try { const uploadStream = IO . createReadStream ( uploadingFile ) ; const streamUploadOptions = JSON . parse ( JSON . stringify ( options ) ) ; if ( uploadFileList . length > 1 ) { delete streamUploadOptions . task ; } const result = await this . streamToDataSet ( session , uploadStream , uploadingDsn , streamUploadOptions ) ; this . log . info ( `Success Uploaded data From ${ uploadingFile } To ${ uploadingDsn }` ) ; const toBePushed = { success : result . success , from : uploadingFile , to : uploadingDsn } ; if ( options . returnEtag ) { toBePushed . etag = result . apiResponse . etag ; } results . push ( toBePushed ) ; } catch ( err ) { this . log . error ( `Failure Uploading data From ${ uploadingFile } To ${ uploadingDsn }` ) ; results . push ( { success : false , from : uploadingFile , to : uploadingDsn , error : err } ) ; uploadError = err ; } } else { results . push ( { success : undefined , from : uploadingFile , to : uploadingDsn } ) ; } } if ( uploadError ) { throw uploadError ; } return { success : true , commandResponse : ZosFilesMessages . dataSetUploadedSuccessfully . message , apiResponse : results } ; } catch ( error ) { return { success : false , commandResponse : error . message , apiResponse : results } ; } } param { AbstractSession } session param { string } ussname param { Buffer } buffer param { IUploadOptions } options returns { Promise < object > } public static async bufferToUssFile ( session , ussname , buffer , options = { } ) { options . binary = options . binary ? options . binary : false ; ImperativeExpect . toNotBeNullOrUndefined ( ussname , ZosFilesMessages . missingUSSFileName . message ) ; ussname = ZosFilesUtils . sanitizeUssPathForRestCall ( ussname ) ; const parameters = ZosFilesConstants . RES_USS_FILES + "/" + ussname ; const headers = this . generateHeadersBasedOnOptions ( options , "buffer" ) ; return ZosmfRestClient . putExpectString ( session , ZosFilesConstants . RESOURCE + parameters , headers , buffer ) ; } deprecated param { AbstractSession } session param { string } ussname param { Buffer } buffer param { boolean } binary returns { Promise < object > } public static async bufferToUSSFile ( session , ussname , buffer , binary = false , localEncoding ? , etag ? , returnEtag ? , responseTimeout ? ) { return this . bufferToUssFile ( session , ussname , buffer , { binary , localEncoding , etag , returnEtag , responseTimeout } ) ; } param { AbstractSession } session param { string } ussname param { Buffer } uploadStream param { IUploadOptions } options returns { Promise < IZosFilesResponse > } public static async streamToUssFile ( session , ussname , uploadStream , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( ussname , ZosFilesMessages . missingUSSFileName . message ) ; ussname = path . posix . normalize ( ussname ) ; ussname = ZosFilesUtils . formatUnixFilepath ( ussname ) ; ussname = encodeURIComponent ( ussname ) ; const parameters = ZosFilesConstants . RES_USS_FILES + "/" + ussname ; const reqHeaders = this . generateHeadersBasedOnOptions ( options , "stream" ) ; const restOptions = { resource : ZosFilesConstants . RESOURCE + parameters , reqHeaders , requestStream : uploadStream , normalizeRequestNewLines : ! options . binary } ; if ( options . returnEtag ) { restOptions . dataToReturn = [ CLIENT_PROPERTY . response ] ; } const uploadRequest = await ZosmfRestClient . putExpectFullResponse ( session , restOptions ) ; const apiResponse = { } ; if ( options . returnEtag ) { apiResponse . etag = uploadRequest . response . headers . etag ; } return { success : true , commandResponse : ZosFilesMessages . dataSetUploadedSuccessfully . message , apiResponse } ; } deprecated param { AbstractSession } session param { string } ussname param { Buffer } uploadStream param { boolean } binary returns { Promise < object > } public static async streamToUSSFile ( session , ussname , uploadStream , binary = false , localEncoding ? , task ? , etag ? ) { return this . streamToUssFile ( session , ussname , uploadStream , { binary , localEncoding , task , etag } ) ; } param session param inputFile param ussname param options returns { Promise < IZosFilesResponse > } public static async fileToUssFile ( session , inputFile , ussname , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( inputFile , ZosFilesMessages . missingInputFile . message ) ; ImperativeExpect . toNotBeNullOrUndefined ( ussname , ZosFilesMessages . missingUSSFileName . message ) ; ImperativeExpect . toNotBeEqual ( ussname , "" , ZosFilesMessages . missingUSSFileName . message ) ; const promise = new Promise ( ( resolve , reject ) => { fs . lstat ( inputFile , ( err , stats ) => { if ( err == null && stats . isFile ( ) ) { resolve ( true ) ; } else if ( err == null ) { reject ( new ImperativeError ( { msg : ZosFilesMessages . missingInputFile . message } ) ) ; } else { reject ( new ImperativeError ( { msg : ZosFilesMessages . nodeJsFsError . message , additionalDetails : err . toString ( ) , causeErrors : err } ) ) ; } } ) ; } ) ; await promise ; const uploadStream = IO . createReadStream ( inputFile ) ; const request = await this . streamToUssFile ( session , ussname , uploadStream , options ) ; const result = { success : true , from : inputFile , to : ussname } ; if ( options . returnEtag ) { result . etag = request . apiResponse . etag ; } return { success : true , commandResponse : ZosFilesMessages . ussFileUploadedSuccessfully . message , apiResponse : result } ; } deprecated param session param inputFile param ussname param binary param localEncoding param task param etag public static async fileToUSSFile ( session , inputFile , ussname , binary = false , localEncoding ? , task ? , etag ? , returnEtag ? ) { return this . fileToUssFile ( session , inputFile , ussname , { binary , localEncoding , task , etag , returnEtag } ) ; } param { AbstractSession } session param { string } inputDirectory param { string } ussname param { IUploadOptions } options returns { Promise < IZosFilesResponse > } public static async dirToUSSDir ( session , inputDirectory , ussname , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( inputDirectory , ZosFilesMessages . missingInputDirectory . message ) ; ImperativeExpect . toNotBeEqual ( inputDirectory , "" , ZosFilesMessages . missingInputDirectory . message ) ; ImperativeExpect . toNotBeNullOrUndefined ( ussname , ZosFilesMessages . missingUSSDirectoryName . message ) ; ImperativeExpect . toNotBeEqual ( ussname , "" , ZosFilesMessages . missingUSSDirectoryName . message ) ; options . binary = options . binary == null ? false : options . binary ; options . recursive = options . recursive == null ? false : options . recursive ; const maxConcurrentRequests = options . maxConcurrentRequests == null ? 1 : options . maxConcurrentRequests ; try { if ( ! IO . isDir ( inputDirectory ) ) { throw new ImperativeError ( { msg : ZosFilesMessages . missingInputDirectory . message } ) ; } const isDirectoryExist = await this . isDirectoryExist ( session , ussname ) ; if ( ! isDirectoryExist ) { await Create . uss ( session , ussname , "directory" ) ; } const filesArray = [ ] ; const files = ZosFilesUtils . getFileListFromPath ( inputDirectory , false ) ; files . forEach ( ( file ) => { let tempBinary = options . binary ; if ( options . filesMap ) { if ( options . filesMap . fileNames . indexOf ( file ) > - 1 ) { tempBinary = options . filesMap . binary ; } } filesArray . push ( { binary : tempBinary , fileName : file } ) ; } ) ; let uploadsInitiated = 0 ; const createFileUploadPromise = ( file ) => { if ( options . task != null ) { options . task . statusMessage = "Uploading ..." + this . formatStringForDisplay ( file . fileName ) ; options . task . percentComplete = Math . floor ( TaskProgress . ONE_HUNDRED_PERCENT * ( uploadsInitiated / filesArray . length ) ) ; uploadsInitiated ++ ; } const fileName = path . normalize ( path . join ( inputDirectory , file . fileName ) ) ; const ussFilePath = path . posix . join ( ussname , file . fileName ) ; return this . uploadFile ( fileName , ussFilePath , session , options ) ; } ; if ( maxConcurrentRequests === 0 ) { await Promise . all ( filesArray . map ( createFileUploadPromise ) ) ; } else { await asyncPool ( maxConcurrentRequests , filesArray , createFileUploadPromise ) ; } const result = { success : true , from : inputDirectory , to : ussname } ; return { success : true , commandResponse : ZosFilesMessages . ussDirUploadedSuccessfully . message , apiResponse : result } ; } catch ( error ) { Logger . getAppLogger ( ) . error ( error ) ; throw error ; } } param { AbstractSession } session param { string } ussname return { Promise < boolean > } public static async isDirectoryExist ( session , ussname ) { ussname = path . posix . normalize ( ussname ) ; ussname = encodeURIComponent ( ussname ) ; const parameters = `${ ZosFilesConstants . RES_USS_FILES }?path=${ ussname }` ; try { const response = await ZosmfRestClient . getExpectJSON ( session , ZosFilesConstants . RESOURCE + parameters , [ ZosmfHeaders . ACCEPT_ENCODING ] ) ; if ( response . items ) { return true ; } } catch ( err ) { if ( err ) { return false ; } } return false ; } param { AbstractSession } session param { string } inputDirectory param { string } ussname param { IUploadOptions } options return { null } public static async dirToUSSDirRecursive ( session , inputDirectory , ussname , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( inputDirectory , ZosFilesMessages . missingInputDirectory . message ) ; ImperativeExpect . toNotBeEqual ( inputDirectory , "" , ZosFilesMessages . missingInputDirectory . message ) ; ImperativeExpect . toNotBeNullOrUndefined ( ussname , ZosFilesMessages . missingUSSDirectoryName . message ) ; ImperativeExpect . toNotBeEqual ( ussname , "" , ZosFilesMessages . missingUSSDirectoryName . message ) ; options . binary = options . binary == null ? false : options . binary ; const maxConcurrentRequests = options . maxConcurrentRequests == null ? 1 : options . maxConcurrentRequests ; const filesArray = [ ] ; let directoriesArray = [ ] ; if ( ! IO . isDir ( inputDirectory ) ) { throw new ImperativeError ( { msg : ZosFilesMessages . missingInputDirectory . message } ) ; } const isDirectoryExist = await this . isDirectoryExist ( session , ussname ) ; if ( ! isDirectoryExist ) { await Create . uss ( session , ussname , "directory" ) ; } directoriesArray = Upload . getDirs ( inputDirectory ) ; if ( options . attributes ) { directoriesArray = directoriesArray . filter ( ( dir ) => { return options . attributes . fileShouldBeUploaded ( dir . fullPath ) ; } ) ; } const files = ZosFilesUtils . getFileListFromPath ( inputDirectory , false ) ; files . forEach ( async ( file ) => { let tempBinary = options . binary ; if ( options . filesMap ) { if ( options . filesMap . fileNames . indexOf ( file ) > - 1 ) { tempBinary = options . filesMap . binary ; } } filesArray . push ( { binary : tempBinary , fileName : file } ) ; } ) ; if ( directoriesArray . length > 0 ) { const createDirUploadPromise = async ( dir ) => { const tempUssname = path . posix . join ( ussname , dir . dirName ) ; const isDirectoryExists = await this . isDirectoryExist ( session , tempUssname ) ; if ( ! isDirectoryExists ) { return Create . uss ( session , tempUssname , "directory" ) ; } } ; if ( maxConcurrentRequests === 0 ) { await Promise . all ( directoriesArray . map ( createDirUploadPromise ) ) ; } else { await asyncPool ( maxConcurrentRequests , directoriesArray , createDirUploadPromise ) ; } } for ( const elem of directoriesArray ) { await this . dirToUSSDirRecursive ( session , elem . fullPath , path . posix . join ( ussname , elem . dirName ) , options ) ; } if ( filesArray . length > 0 ) { let uploadsInitiated = 0 ; const createUploadPromise = ( file ) => { if ( options . task != null ) { options . task . statusMessage = "Uploading ..." + this . formatStringForDisplay ( file . fileName ) ; options . task . percentComplete = Math . floor ( TaskProgress . ONE_HUNDRED_PERCENT * ( uploadsInitiated / filesArray . length ) ) ; uploadsInitiated ++ ; } const filePath = path . normalize ( path . join ( inputDirectory , file . fileName ) ) ; const ussFilePath = path . posix . join ( ussname , file . fileName ) ; return this . uploadFile ( filePath , ussFilePath , session , options ) ; } ; if ( maxConcurrentRequests === 0 ) { await Promise . all ( filesArray . map ( createUploadPromise ) ) ; } else { await asyncPool ( maxConcurrentRequests , filesArray , createUploadPromise ) ; } } const result = { success : true , from : inputDirectory , to : ussname } ; return { success : true , commandResponse : ZosFilesMessages . ussDirUploadedSuccessfully . message , apiResponse : result } ; } private static async uploadFile ( localPath , ussPath , session , options ) { let tempBinary ; if ( options . attributes ) { await this . uploadFileAndTagBasedOnAttributes ( localPath , ussPath , session , options . attributes ) ; } else { if ( options . filesMap ) { if ( options . filesMap . fileNames . indexOf ( path . basename ( localPath ) ) > - 1 ) { tempBinary = options . filesMap . binary ; } else { tempBinary = options . binary ; } } else { tempBinary = options . binary ; } await this . fileToUssFile ( session , localPath , ussPath , { binary : tempBinary } ) ; } } private static async uploadFileAndTagBasedOnAttributes ( localPath , ussPath , session , attributes ) { if ( attributes . fileShouldBeUploaded ( localPath ) ) { const binary = attributes . getFileTransferMode ( localPath ) === TransferMode . BINARY ; if ( binary ) { await this . fileToUssFile ( session , localPath , ussPath , { binary } ) ; } else { await this . fileToUssFile ( session , localPath , ussPath , { binary , localEncoding : attributes . getLocalEncoding ( localPath ) } ) ; } const tag = attributes . getRemoteEncoding ( localPath ) ; if ( tag === Tag . BINARY . valueOf ( ) ) { await Utilities . chtag ( session , ussPath , Tag . BINARY ) ; } else { await Utilities . chtag ( session , ussPath , Tag . TEXT , tag ) ; } } } returns { Logger } private static get log ( ) : Logger { return Logger . getAppLogger ( ) ; } param { string } dirPath private static hasDirs ( dirPath ) { const directories = fs . readdirSync ( dirPath ) . filter ( ( file ) => IO . isDir ( path . normalize ( path . join ( dirPath , file ) ) ) ) ; if ( directories . length === 0 ) { return false ; } else { return true ; } } param dirPath private static getDirs ( dirPath ) { const response = [ ] ; if ( Upload . hasDirs ( dirPath ) ) { const directories = fs . readdirSync ( dirPath ) . filter ( ( file ) => IO . isDir ( path . normalize ( path . join ( dirPath , file ) ) ) ) ; for ( let index = 0 ; index < directories . length ; index ++ ) { const dirFullPath = path . normalize ( path . join ( dirPath , directories [ index ] ) ) ; response . push ( { dirName : directories [ index ] , fullPath : dirFullPath } ) ; } } return response ; } param stringInput private static formatStringForDisplay ( stringInput ) { const LAST_FIFTEEN_CHARS = - 15 ; const stringToDisplay = stringInput . split ( path . sep ) . splice ( - 1 , 1 ) . toString ( ) . slice ( LAST_FIFTEEN_CHARS ) ; const result = stringToDisplay === "" ? "all files" : stringToDisplay ; return result ; } param { IUploadOptions } options param { string } context private static generateHeadersBasedOnOptions ( options , context ? ) { const reqHeaders = [ ] ; switch ( context ) { case "stream" : case "buffer" : if ( options . binary ) { reqHeaders . push ( ZosmfHeaders . OCTET_STREAM ) ; reqHeaders . push ( ZosmfHeaders . X_IBM_BINARY ) ; } else if ( options . localEncoding ) { reqHeaders . push ( { "Content-Type" : options . localEncoding } ) ; reqHeaders . push ( ZosmfHeaders . X_IBM_TEXT ) ; } else if ( options . encoding ) { const keys = Object . keys ( ZosmfHeaders . X_IBM_TEXT ) ; const value = ZosmfHeaders . X_IBM_TEXT [ keys [ 0 ] ] + ZosmfHeaders . X_IBM_TEXT_ENCODING + options . encoding ; const header = Object . create ( ZosmfHeaders . X_IBM_TEXT ) ; header [ keys [ 0 ] ] = value ; reqHeaders . push ( header ) ; } else { reqHeaders . push ( ZosmfHeaders . TEXT_PLAIN ) ; } reqHeaders . push ( ZosmfHeaders . ACCEPT_ENCODING ) ; if ( options . responseTimeout != null ) { reqHeaders . push ( { [ ZosmfHeaders . X_IBM_RESPONSE_TIMEOUT ] : options . responseTimeout . toString ( ) } ) ; } break ; default : { const headers = ZosFilesUtils . generateHeadersBasedOnOptions ( options ) ; const contentTypeHeaders = [ ... Object . keys ( ZosmfHeaders . X_IBM_BINARY ) , ... Object . keys ( ZosmfHeaders . X_IBM_TEXT ) ] ; if ( ! headers . find ( ( x ) => contentTypeHeaders . includes ( Object . keys ( x ) [ 0 ] ) ) ) { reqHeaders . push ( ZosmfHeaders . X_IBM_TEXT ) ; } reqHeaders . push ( ... headers ) ; break ; } } if ( options . recall ) { switch ( options . recall . toLowerCase ( ) ) { case "wait" : reqHeaders . push ( ZosmfHeaders . X_IBM_MIGRATED_RECALL_WAIT ) ; break ; case "nowait" : reqHeaders . push ( ZosmfHeaders . X_IBM_MIGRATED_RECALL_NO_WAIT ) ; break ; case "error" : reqHeaders . push ( ZosmfHeaders . X_IBM_MIGRATED_RECALL_ERROR ) ; break ; default : reqHeaders . push ( ZosmfHeaders . X_IBM_MIGRATED_RECALL_NO_WAIT ) ; break ; } } if ( options . etag ) { reqHeaders . push ( { "If-Match" : options . etag } ) ; } if ( options . returnEtag ) { reqHeaders . push ( ZosmfHeaders . X_IBM_RETURN_ETAG ) ; } return reqHeaders ; } }