import { AbstractSession , ImperativeExpect , IO , Logger , TaskProgress , ImperativeError } from "@zowe/imperative" ; import { posix } from "path" ; import * as util from "util" ; import { ZosmfRestClient , IHeaderContent , ZosmfHeaders , 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/List" ; import { IDownloadOptions } from "./doc/IDownloadOptions" ; import { IRestClientResponse } from "../../doc/IRestClientResponse" ; import { CLIENT_PROPERTY } from "../../doc/types/ZosmfRestClientProperties" ; import { IOptionsFullResponse } from "../../doc/IOptionsFullResponse" ; /**
 * This class holds helper functions that are used to download data sets, members and more through the z/OS MF APIs
 */ export class Download { param { AbstractSession } session param { string } dataSetName param { IDownloadOptions } options returns { Promise < IZosFilesResponse > } throws throws {Error} When the  ZosmfRestClient throws an error
     *
     *  example see https public static async dataSet ( session , dataSetName , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; ImperativeExpect . toNotBeEqual ( dataSetName , "" , ZosFilesMessages . missingDatasetName . message ) ; try { let endpoint = posix . join ( ZosFilesConstants . RESOURCE , ZosFilesConstants . RES_DS_FILES ) ; if ( options . volume ) { endpoint = posix . join ( endpoint , `-(${ options . volume })` ) ; } endpoint = posix . join ( endpoint , dataSetName ) ; Logger . getAppLogger ( ) . debug ( `Endpoint: ${ endpoint }` ) ; const reqHeaders = ZosFilesUtils . generateHeadersBasedOnOptions ( options ) ; let extension = ZosFilesUtils . DEFAULT_FILE_EXTENSION ; if ( options . extension != null ) { extension = options . extension ; } const destination = ( ( ) => { if ( options . file ) { return options . file ; } let generatedFilePath = ZosFilesUtils . getDirsFromDataSet ( dataSetName ) ; if ( options . preserveOriginalLetterCase ) { generatedFilePath = generatedFilePath . toUpperCase ( ) ; } return generatedFilePath + IO . normalizeExtension ( extension ) ; } ) ( ) ; IO . createDirsSyncFromFilePath ( destination ) ; const writeStream = IO . createWriteStream ( destination ) ; const requestOptions = { resource : endpoint , reqHeaders , responseStream : writeStream , normalizeResponseNewLines : ! options . binary , task : options . task } ; if ( options . returnEtag ) { requestOptions . reqHeaders . push ( ZosmfHeaders . X_IBM_RETURN_ETAG ) ; requestOptions . dataToReturn = [ CLIENT_PROPERTY . response ] ; } const request = await ZosmfRestClient . getExpectFullResponse ( session , requestOptions ) ; const apiResponse = { } ; if ( options . returnEtag ) { apiResponse . etag = request . response . headers . etag ; } return { success : true , commandResponse : util . format ( ZosFilesMessages . datasetDownloadedSuccessfully . message , destination ) , apiResponse } ; } catch ( error ) { Logger . getAppLogger ( ) . error ( error ) ; throw error ; } } param { AbstractSession } session param { string } dataSetName param { IDownloadOptions } options returns { Promise < IZosFilesResponse > } throws throws {Error} When the  ZosmfRestClient throws an error
     *
     *  example see https public static async allMembers ( session , dataSetName , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( dataSetName , ZosFilesMessages . missingDatasetName . message ) ; ImperativeExpect . toNotBeEqual ( dataSetName , "" , ZosFilesMessages . missingDatasetName . message ) ; try { const response = await List . allMembers ( session , dataSetName , { volume : options . volume , responseTimeout : options . responseTimeout } ) ; const memberList = response . apiResponse . items ; if ( memberList . length === 0 ) { return { success : false , commandResponse : ZosFilesMessages . noMembersFound . message , apiResponse : response . apiResponse } ; } const baseDir = ( ( ) => { if ( options . directory ) { return options . directory ; } let generatedDirectory = ZosFilesUtils . getDirsFromDataSet ( dataSetName ) ; if ( options . preserveOriginalLetterCase ) { generatedDirectory = generatedDirectory . toUpperCase ( ) ; } return generatedDirectory ; } ) ( ) ; const downloadErrors = [ ] ; const failedMembers = [ ] ; let downloadsInitiated = 0 ; let extension = ZosFilesUtils . DEFAULT_FILE_EXTENSION ; if ( options . extension != null ) { extension = options . extension ; } param mem const createDownloadPromise = ( mem ) => { if ( options . task != null ) { options . task . statusMessage = "Downloading " + mem . member ; options . task . percentComplete = Math . floor ( TaskProgress . ONE_HUNDRED_PERCENT * ( downloadsInitiated / memberList . length ) ) ; downloadsInitiated ++ ; } const fileName = options . preserveOriginalLetterCase ? mem . member : mem . member . toLowerCase ( ) ; return this . dataSet ( session , `${ dataSetName }(${ mem . member })` , { volume : options . volume , file : baseDir + IO . FILE_DELIM + fileName + IO . normalizeExtension ( extension ) , binary : options . binary , encoding : options . encoding , responseTimeout : options . responseTimeout } ) . catch ( ( err ) => { if ( options . failFast || options . failFast === undefined ) { throw err ; } downloadErrors . push ( err ) ; failedMembers . push ( fileName ) ; IO . deleteFile ( baseDir + IO . FILE_DELIM + fileName + IO . normalizeExtension ( extension ) ) ; } ) ; } ; const maxConcurrentRequests = options . maxConcurrentRequests == null ? 1 : options . maxConcurrentRequests ; if ( maxConcurrentRequests === 0 ) { await Promise . all ( memberList . map ( createDownloadPromise ) ) ; } else { await asyncPool ( maxConcurrentRequests , memberList , createDownloadPromise ) ; } if ( downloadErrors . length > 0 ) { throw new ImperativeError ( { msg : ZosFilesMessages . memberDownloadFailed . message + failedMembers . join ( "\n" ) + "\n\n" + downloadErrors . map ( ( err ) => err . message ) . join ( "\n" ) , causeErrors : downloadErrors , additionalDetails : failedMembers . join ( "\n" ) } ) ; } return { success : true , commandResponse : util . format ( ZosFilesMessages . datasetDownloadedSuccessfully . message , baseDir ) , apiResponse : response . apiResponse } ; } catch ( error ) { Logger . getAppLogger ( ) . error ( error ) ; throw error ; } } param { AbstractSession } session param { string } ussFileName param { IDownloadOptions } options returns { Promise < IZosFilesResponse > } throws throws {Error} When the  ZosmfRestClient throws an error
      public static async ussFile ( session , ussFileName , options = { } ) { ImperativeExpect . toNotBeNullOrUndefined ( ussFileName , ZosFilesMessages . missingUSSFileName . message ) ; ImperativeExpect . toNotBeEqual ( ussFileName , "" , ZosFilesMessages . missingUSSFileName . message ) ; try { if ( ussFileName . substr ( 0 , 1 ) === "/" ) { ussFileName = ussFileName . substr ( 1 ) ; } const destination = options . file || posix . normalize ( posix . basename ( ussFileName ) ) ; IO . createDirsSyncFromFilePath ( destination ) ; const writeStream = IO . createWriteStream ( destination ) ; ussFileName = posix . normalize ( ussFileName ) ; if ( ussFileName . substr ( 0 , 1 ) === "/" ) { ussFileName = ussFileName . substr ( 1 ) ; } ussFileName = encodeURIComponent ( ussFileName ) ; const endpoint = posix . join ( ZosFilesConstants . RESOURCE , ZosFilesConstants . RES_USS_FILES , ussFileName ) ; const reqHeaders = ZosFilesUtils . generateHeadersBasedOnOptions ( options ) ; const requestOptions = { resource : endpoint , reqHeaders , responseStream : writeStream , normalizeResponseNewLines : ! options . binary , task : options . task } ; if ( options . returnEtag ) { requestOptions . reqHeaders . push ( ZosmfHeaders . X_IBM_RETURN_ETAG ) ; requestOptions . dataToReturn = [ CLIENT_PROPERTY . response ] ; } const request = await ZosmfRestClient . getExpectFullResponse ( session , requestOptions ) ; const apiResponse = { } ; if ( options . returnEtag ) { apiResponse . etag = request . response . headers . etag ; } return { success : true , commandResponse : util . format ( ZosFilesMessages . ussFileDownloadedSuccessfully . message , destination ) , apiResponse } ; } catch ( error ) { Logger . getAppLogger ( ) . error ( error ) ; throw error ; } } }