UNPKG

@zowe/cli

Version:

Zowe CLI is a command line interface (CLI) that provides a simple and streamlined way to interact with IBM z/OS.

243 lines 12.9 kB
"use strict"; /* * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v20.html * * SPDX-License-Identifier: EPL-2.0 * * Copyright Contributors to the Zowe Project. * */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const imperative_1 = require("@zowe/imperative"); const path_1 = require("path"); const util = require("util"); const rest_1 = require("../../../../../rest"); const ZosmfHeaders_1 = require("../../../../../rest/src/ZosmfHeaders"); const ZosFiles_constants_1 = require("../../constants/ZosFiles.constants"); const ZosFiles_messages_1 = require("../../constants/ZosFiles.messages"); const ZosFilesUtils_1 = require("../../utils/ZosFilesUtils"); const List_1 = require("../list/List"); const utils_1 = require("../../../../../utils"); /** * This class holds helper functions that are used to download data sets, members and more through the z/OS MF APIs */ class Download { /** * Retrieve data sets and/or members contents and save them in your local workspace * * @param {AbstractSession} session - z/OS MF connection info * @param {string} dataSetName - contains the data set name * @param {IDownloadOptions} [options={}] - contains the options to be sent * * @returns {Promise<IZosFilesResponse>} A response indicating the outcome of the API * * @throws {ImperativeError} data set name must be set * @throws {Error} When the {@link ZosmfRestClient} throws an error * * @example * ```typescript * * // Download "USER.DATA.SET.PS" to "user/data/set/ps.txt" * await Download.dataSet(session, "USER.DATA.SET.PS"); * * // Download "USER.DATA.SET.PDS(MEMBER)" to "user/data/set/pds/member.txt" * await Download.dataSet(session, "USER.DATA.SET.PDS(MEMBER)"); * * // Download "USER.DATA.SET" to "./path/to/file.txt" * await Download.dataSet(session, "USER.DATA.SET", {file: "./path/to/file.txt"}); * ``` * * @see https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.izua700/IZUHPINFO_API_GetReadDataSet.htm */ static dataSet(session, dataSetName, options = {}) { return __awaiter(this, void 0, void 0, function* () { // required imperative_1.ImperativeExpect.toNotBeNullOrUndefined(dataSetName, ZosFiles_messages_1.ZosFilesMessages.missingDatasetName.message); imperative_1.ImperativeExpect.toNotBeEqual(dataSetName, "", ZosFiles_messages_1.ZosFilesMessages.missingDatasetName.message); try { // Format the endpoint to send the request to let endpoint = path_1.posix.join(ZosFiles_constants_1.ZosFilesConstants.RESOURCE, ZosFiles_constants_1.ZosFilesConstants.RES_DS_FILES); if (options.volume) { endpoint = path_1.posix.join(endpoint, `-(${options.volume})`); } endpoint = path_1.posix.join(endpoint, dataSetName); imperative_1.Logger.getAppLogger().debug(`Endpoint: ${endpoint}`); let reqHeaders = []; if (options.binary) { reqHeaders = [ZosmfHeaders_1.ZosmfHeaders.X_IBM_BINARY]; } // Get contents of the data set let extension = ZosFilesUtils_1.ZosFilesUtils.DEFAULT_FILE_EXTENSION; if (options.extension != null) { extension = options.extension; } // Get a proper destination for the file to be downloaded // If the "file" is not provided, we create a folder structure similar to the data set name // Note that the "extension" options do not affect the destination if the "file" options were provided const destination = options.file || ZosFilesUtils_1.ZosFilesUtils.getDirsFromDataSet(dataSetName) + imperative_1.IO.normalizeExtension(extension); imperative_1.IO.createDirsSyncFromFilePath(destination); const writeStream = imperative_1.IO.createWriteStream(destination); yield rest_1.ZosmfRestClient.getStreamed(session, endpoint, reqHeaders, writeStream, !options.binary, options.task); return { success: true, commandResponse: util.format(ZosFiles_messages_1.ZosFilesMessages.datasetDownloadedSuccessfully.message, destination), apiResponse: {} }; } catch (error) { imperative_1.Logger.getAppLogger().error(error); throw error; } }); } /** * Retrieve all members from a PDS and save them in your local workspace * * @param {AbstractSession} session - z/OS MF connection info * @param {string} dataSetName - contains the data set name * @param {IDownloadOptions} [options={}] - contains the options to be sent * * @returns {Promise<IZosFilesResponse>} A response indicating the outcome of the API * * @throws {ImperativeError} data set name must be set * @throws {Error} When the {@link ZosmfRestClient} throws an error * * @example * ```typescript * * // Download all members of "USER.DATA.SET.PDS" to "user/data/set/pds/" * await Download.allMembers(session, "USER.DATA.SET.PDS"); * * // Download all members of "USER.DATA.SET.PDS" to "./path/to/dir/" * await Download.allMembers(session, "USER.DATA.SET.PDS", {directory: "./path/to/dir/"}); * ``` * * @see https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.izua700/IZUHPINFO_API_GetReadDataSet.htm */ static allMembers(session, dataSetName, options = {}) { return __awaiter(this, void 0, void 0, function* () { // required imperative_1.ImperativeExpect.toNotBeNullOrUndefined(dataSetName, ZosFiles_messages_1.ZosFilesMessages.missingDatasetName.message); imperative_1.ImperativeExpect.toNotBeEqual(dataSetName, "", ZosFiles_messages_1.ZosFilesMessages.missingDatasetName.message); try { const response = yield List_1.List.allMembers(session, dataSetName, { volume: options.volume }); const memberList = response.apiResponse.items; if (memberList.length === 0) { return { success: false, commandResponse: ZosFiles_messages_1.ZosFilesMessages.noMembersFound.message, apiResponse: response.apiResponse }; } const baseDir = options.directory || ZosFilesUtils_1.ZosFilesUtils.getDirsFromDataSet(dataSetName); let downloadsInitiated = 0; let extension = ZosFilesUtils_1.ZosFilesUtils.DEFAULT_FILE_EXTENSION; if (options.extension != null) { extension = options.extension; } /** * Function that takes a member and turns it into a promise to download said member * @param mem - an object with a "member" field containing the name of the data set member */ const createDownloadPromise = (mem) => { // update the progress bar if any if (options.task != null) { options.task.statusMessage = "Downloading " + mem.member; options.task.percentComplete = Math.floor(imperative_1.TaskProgress.ONE_HUNDRED_PERCENT * (downloadsInitiated / memberList.length)); downloadsInitiated++; } return this.dataSet(session, `${dataSetName}(${mem.member})`, { volume: options.volume, file: baseDir + imperative_1.IO.FILE_DELIM + mem.member.toLowerCase() + imperative_1.IO.normalizeExtension(extension), binary: options.binary }); }; const maxConcurrentRequests = options.maxConcurrentRequests == null ? 1 : options.maxConcurrentRequests; if (maxConcurrentRequests === 0) { yield Promise.all(memberList.map(createDownloadPromise)); } else { yield utils_1.asyncPool(maxConcurrentRequests, memberList, createDownloadPromise); } return { success: true, commandResponse: util.format(ZosFiles_messages_1.ZosFilesMessages.datasetDownloadedSuccessfully.message, baseDir), apiResponse: response.apiResponse }; } catch (error) { imperative_1.Logger.getAppLogger().error(error); throw error; } }); } /** * Retrieve USS file content and save it in your local workspace. * * @param {AbstractSession} session - z/OS MF connection info * @param {string} ussFileName - contains the USS file name * @param {IDownloadOptions} [options={}] - contains the options to be sent * * @returns {Promise<IZosFilesResponse>} A response indicating the outcome of the API * * @throws {ImperativeError} USS file name must be set * @throws {Error} When the {@link ZosmfRestClient} throws an error */ static ussFile(session, ussFileName, options = {}) { return __awaiter(this, void 0, void 0, function* () { // required imperative_1.ImperativeExpect.toNotBeNullOrUndefined(ussFileName, ZosFiles_messages_1.ZosFilesMessages.missingUSSFileName.message); imperative_1.ImperativeExpect.toNotBeEqual(ussFileName, "", ZosFiles_messages_1.ZosFilesMessages.missingUSSFileName.message); try { // Get a proper destination for the file to be downloaded // If the "file" is not provided, we create a folder structure similar to the uss file structure if (ussFileName.substr(0, 1) === "/") { ussFileName = ussFileName.substr(1); } const destination = options.file || path_1.posix.normalize(path_1.posix.basename(ussFileName)); imperative_1.IO.createDirsSyncFromFilePath(destination); const writeStream = imperative_1.IO.createWriteStream(destination); ussFileName = path_1.posix.normalize(ussFileName); // Get a proper destination for the file to be downloaded // If the "file" is not provided, we create a folder structure similar to the uss file structure if (ussFileName.substr(0, 1) === "/") { ussFileName = ussFileName.substr(1); } ussFileName = encodeURIComponent(ussFileName); const endpoint = path_1.posix.join(ZosFiles_constants_1.ZosFilesConstants.RESOURCE, ZosFiles_constants_1.ZosFilesConstants.RES_USS_FILES, ussFileName); let reqHeaders = []; if (options.binary) { reqHeaders = [ZosmfHeaders_1.ZosmfHeaders.X_IBM_BINARY]; } yield rest_1.ZosmfRestClient.getStreamed(session, endpoint, reqHeaders, writeStream, !options.binary, options.task); return { success: true, commandResponse: util.format(ZosFiles_messages_1.ZosFilesMessages.ussFileDownloadedSuccessfully.message, destination), apiResponse: {} }; } catch (error) { imperative_1.Logger.getAppLogger().error(error); throw error; } }); } } exports.Download = Download; //# sourceMappingURL=Download.js.map