UNPKG

@zowe/imperative

Version:
204 lines 11 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 utilities_1 = require("../../../../../utilities"); const config_1 = require("../../../../../config"); const ConfigBuilder_1 = require("../../../../../config/src/ConfigBuilder"); const ConfigUtils_1 = require("../../../../../config/src/ConfigUtils"); const OverridesLoader_1 = require("../../../OverridesLoader"); const JSONC = require("comment-json"); const lodash = require("lodash"); const jest_diff_1 = require("jest-diff"); const stripAnsi = require("strip-ansi"); /** * Init config */ class InitHandler { /** * Process the command and input. * * @param {IHandlerParameters} params Parameters supplied by yargs * * @throws {ImperativeError} */ process(params) { return __awaiter(this, void 0, void 0, function* () { var _a; this.params = params; this.promptProps = []; // Load the config and set the active layer according to user options yield OverridesLoader_1.OverridesLoader.ensureCredentialManagerLoaded(); const config = utilities_1.ImperativeConfig.instance.config; const globalConfig = ((_a = params.arguments) === null || _a === void 0 ? void 0 : _a.globalConfig) ? true : false; const configDir = globalConfig ? null : process.cwd(); config.api.layers.activate(params.arguments.userConfig, globalConfig, configDir); const layer = config.api.layers.get(); // Do a dry run if dryRun flag is present. Otherwise, initialize or overwrite the config if (params.arguments.dryRun && params.arguments.dryRun === true) { let dryRun = yield this.initForDryRun(config, params.arguments.userConfig, globalConfig); // Merge and display, do not save // Handle if the file doesn't actually exist let original = layer; let originalProperties; if (original.exists === false) { originalProperties = {}; } else { // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 originalProperties = JSONC.parse(JSONC.stringify(original.properties, null, config_1.ConfigConstants.INDENT)); // Hide secure stuff for (const secureProp of utilities_1.ImperativeConfig.instance.config.api.secure.secureFields(original)) { if (lodash.has(originalProperties, secureProp)) { lodash.unset(originalProperties, secureProp); } } } // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 const dryRunProperties = JSONC.parse(JSONC.stringify(dryRun.properties, null, config_1.ConfigConstants.INDENT)); // Hide secure stuff for (const secureProp of utilities_1.ImperativeConfig.instance.config.api.secure.findSecure(dryRun.properties.profiles, "profiles")) { if (lodash.has(dryRunProperties, secureProp)) { lodash.unset(dryRunProperties, secureProp); } } original = JSONC.stringify(originalProperties, null, config_1.ConfigConstants.INDENT); dryRun = JSONC.stringify(dryRunProperties, null, config_1.ConfigConstants.INDENT); let jsonDiff = (0, jest_diff_1.diff)(original, dryRun, { aAnnotation: "Removed", bAnnotation: "Added", aColor: utilities_1.TextUtils.chalk.red, bColor: utilities_1.TextUtils.chalk.green }); if (stripAnsi(jsonDiff) === "Compared values have no visual difference.") { jsonDiff = dryRun; } params.response.console.log(jsonDiff); params.response.data.setObj(jsonDiff); } else { yield this.initWithSchema(config, params.arguments.userConfig, globalConfig, params.arguments.overwrite && params.arguments.forSure); if (params.arguments.prompt !== false && config.api.secure.loadFailed && config.api.secure.secureFields().length > 0) { const warning = ConfigUtils_1.ConfigUtils.secureSaveError(); let message = "Warning:\n" + warning.message + " Skipped prompting for credentials."; if (warning.additionalDetails) { message += `\n\n${warning.additionalDetails}\n`; } params.response.console.log(utilities_1.TextUtils.chalk.yellow(message)); } // Write the active created/updated config layer yield config.save(); params.response.console.log(`Saved config template to ${layer.path}`); if (params.arguments.edit && params.arguments.edit === true) { yield utilities_1.ProcessUtils.openInEditor(utilities_1.ImperativeConfig.instance.config.api.layers.get().path, params.arguments.editor); } } }); } /** * Creates JSON template for config. Also creates a schema file in the same * folder alongside the config. * @param config Config object to be populated * @param user If true, properties will be left empty for user config * @param globalConfig Is the config to be a global config? * @param overwrite Shall we overwrite an existing config? */ initWithSchema(config, user, globalConfig, overwrite) { return __awaiter(this, void 0, void 0, function* () { var _a; const opts = {}; if (!user) { opts.populateProperties = true; opts.getValueBack = this.promptForProp.bind(this); } // Build new config and merge with existing layer or overwrite it if overwrite & forSure options are present const newConfig = yield ConfigBuilder_1.ConfigBuilder.build(utilities_1.ImperativeConfig.instance.loadedConfig, globalConfig, opts); if (overwrite) { config.api.layers.set(newConfig); } else { const oldConfig = config.layerActive().properties; const baseProfileNm = ConfigUtils_1.ConfigUtils.formGlobOrProjProfileNm("base", globalConfig); if (((_a = oldConfig.profiles[baseProfileNm]) === null || _a === void 0 ? void 0 : _a.properties) != null) { // Remove values that should be overwritten from old base profile for (const propName of Object.keys(oldConfig.profiles[baseProfileNm].properties)) { const newPropValue = newConfig.profiles[baseProfileNm].properties[propName]; if (this.promptProps.includes(propName) && newPropValue != null && newPropValue !== "") { delete oldConfig.profiles[baseProfileNm].properties[propName]; } } } config.api.layers.merge(newConfig); } // Build the schema and write it to disk config_1.ConfigSchema.updateSchema(); }); } /** * Do a dry run of creating JSON template for config. * Also create a schema file in the same folder alongside the config. * @param config Config object to be populated * @param user If true, properties will be left empty for user config * @param globalConfig Is the config to be a global config? */ initForDryRun(config, user, globalConfig) { return __awaiter(this, void 0, void 0, function* () { const opts = {}; if (!user) { opts.populateProperties = true; } // Build new config and merge with existing layer const newConfig = yield ConfigBuilder_1.ConfigBuilder.build(utilities_1.ImperativeConfig.instance.loadedConfig, globalConfig, opts); return config.api.layers.merge(newConfig, true); }); } /** * Prompts for the value of a property on the CLI. Returns null if `--prompt false` * argument is passed, or prompt times out, or a blank value is entered. * @param propName The name of the property * @param property The profile property definition */ promptForProp(propName, property) { return __awaiter(this, void 0, void 0, function* () { var _a; // skip prompting in CI environment if (this.params.arguments.prompt === false || utilities_1.ImperativeConfig.instance.config.api.secure.loadFailed) { return null; } // get the summary and value let propDesc = propName; if (((_a = property.optionDefinition) === null || _a === void 0 ? void 0 : _a.description) != null) { propDesc += ` (${property.optionDefinition.description})`; } this.promptProps.push(propName); const propValue = yield this.params.response.console.prompt(`Enter ${propDesc} ${config_1.ConfigConstants.SKIP_PROMPT}`, { hideText: property.secure }); // coerce to correct type if (propValue && propValue.trim().length > 0) { // TODO How to handle profile property with multiple types // Same TODO as `private ConfigBuilder.getDefaultValue()` const propType = Array.isArray(property.type) ? property.type[0] : property.type; return ConfigUtils_1.ConfigUtils.coercePropValue(propValue, propType); } return propValue || null; }); } } exports.default = InitHandler; //# sourceMappingURL=init.handler.js.map