UNPKG

@zowe/imperative

Version:
211 lines 9.28 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. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigLayers = void 0; const fs = require("fs"); const path = require("path"); const JSONC = require("comment-json"); const lodash = require("lodash"); const error_1 = require("../../../error"); const ConfigConstants_1 = require("../ConfigConstants"); const ConfigApi_1 = require("./ConfigApi"); const logger_1 = require("../../../logger"); /** * API Class for manipulating config layers. */ class ConfigLayers extends ConfigApi_1.ConfigApi { // _______________________________________________________________________ /** * Read a config layer from disk into memory for application use. * * @param opts The user and global flags that indicate which of the four * config files (aka layers) is to be read. */ read(opts) { // Attempt to populate the layer const layer = opts ? this.mConfig.findLayer(opts.user, opts.global) : this.mConfig.layerActive(); if (fs.existsSync(layer.path)) { let fileContents; try { fileContents = fs.readFileSync(layer.path); } catch (e) { throw new error_1.ImperativeError({ msg: `An error was encountered while trying to read the file '${layer.path}'.\nError details: ${e.message}`, suppressDump: true }); } try { // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 layer.properties = JSONC.parse(fileContents.toString()); layer.exists = true; } catch (e) { const msg = `Error parsing JSON in the file '${layer.path}'.\n` + `Please check this configuration file for errors.\nError details: ${e.message}\nLine ${e.line}, Column ${e.column}`; if (!(opts === null || opts === void 0 ? void 0 : opts.ignoreErrors)) { throw new error_1.ImperativeError({ msg: msg, suppressDump: true }); } else { logger_1.Logger.getConsoleLogger().error(msg); } } this.mConfig.api.secure.loadCached(opts); } else if (layer.exists) { layer.properties = {}; layer.exists = false; } // Populate any undefined defaults layer.properties.profiles = layer.properties.profiles || {}; layer.properties.defaults = layer.properties.defaults || {}; } // _______________________________________________________________________ /** * Write a config layer to disk. * * @param opts The user and global flags that indicate which of the four * config files (aka layers) is to be written. */ write(opts) { // TODO: should we prevent a write if there is no vault // TODO: specified and there are secure fields?? // If fields are marked as secure const layer = opts ? this.mConfig.findLayer(opts.user, opts.global) : this.mConfig.layerActive(); // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 const layerCloned = JSONC.parse(JSONC.stringify(layer, null, ConfigConstants_1.ConfigConstants.INDENT)); this.mConfig.api.secure.cacheAndPrune(layerCloned); // Write the layer try { fs.writeFileSync(layer.path, JSONC.stringify(layerCloned.properties, null, ConfigConstants_1.ConfigConstants.INDENT)); } catch (e) { throw new error_1.ImperativeError({ msg: `error writing "${layer.path}": ${e.message}` }); } layer.exists = true; } // _______________________________________________________________________ /** * Select which layer is the currently active layer. * * @param user True if you want the user layer. * @param global True if you want the global layer. * @param inDir The directory to which you want to set the file path * for this layer. */ activate(user, global, inDir) { this.mConfig.mActive.user = user; this.mConfig.mActive.global = global; if (inDir != null) { const layer = this.mConfig.layerActive(); // Load config layer if file path has changed if (inDir !== path.dirname(layer.path)) { layer.path = path.join(inDir, path.basename(layer.path)); this.read(); } } } // _______________________________________________________________________ /** * Gets a json object that represents the currently active layer. * * @returns The json object */ get() { // Note: Add indentation to allow comments to be accessed via config.api.layers.get(), otherwise use layerActive() // return JSONC.parse(JSONC.stringify(this.mConfig.layerActive(), null, ConfigConstants.INDENT)); // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 return JSONC.parse(JSONC.stringify(this.mConfig.layerActive(), null, ConfigConstants_1.ConfigConstants.INDENT)); } // _______________________________________________________________________ /** * Set the the currently active layer to the supplied json object. * * @param user True if you want the user layer. */ set(cnfg) { for (const i in this.mConfig.mLayers) { if (this.mConfig.mLayers[i].user === this.mConfig.mActive.user && this.mConfig.mLayers[i].global === this.mConfig.mActive.global) { this.mConfig.mLayers[i].properties = cnfg; this.mConfig.mLayers[i].properties.defaults = this.mConfig.mLayers[i].properties.defaults || {}; this.mConfig.mLayers[i].properties.profiles = this.mConfig.mLayers[i].properties.profiles || {}; } } } // _______________________________________________________________________ /** * Merge properties from the supplied Config object into the active layer. * If dryRun is specified, merge is applied to a copy of the layer and returned. * If dryRun is not specified, merge is applied directly to the layer and nothing is returned. * * @param cnfg The Config object to merge. * @returns The merged config layer or void */ merge(cnfg, dryRun = false) { var _a; let layer; if (dryRun) { // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 layer = JSONC.parse(JSONC.stringify(this.mConfig.layerActive(), null, ConfigConstants_1.ConfigConstants.INDENT)); } else { layer = this.mConfig.layerActive(); } layer.properties.profiles = lodash.mergeWith(cnfg.profiles, layer.properties.profiles, (obj, src) => { if (lodash.isArray(obj) && lodash.isArray(src)) { // Typecasting because of this issue: https://github.com/kaelzhang/node-comment-json/issues/42 const temp = JSONC.parse(JSONC.stringify(obj, null, ConfigConstants_1.ConfigConstants.INDENT)); src.forEach((val, idx) => { if (!temp.includes(val)) { temp.splice(idx, 0, val); } }); return temp; } }); layer.properties.defaults = lodash.merge(cnfg.defaults, layer.properties.defaults); for (const pluginName of cnfg.plugins || []) { if (layer.properties.plugins == null) { layer.properties.plugins = [pluginName]; } else if (!((_a = layer.properties.plugins) === null || _a === void 0 ? void 0 : _a.includes(pluginName))) { layer.properties.plugins.push(pluginName); } } if (cnfg.autoStore != null) { layer.properties.autoStore = cnfg.autoStore; } if (dryRun) { return layer; } } // _______________________________________________________________________ /** * Finds the highest priority layer where a profile is stored. * @param profileName Profile name to search for * @returns User and global properties, or undefined if profile does not exist */ find(profileName) { const profilePath = this.mConfig.api.profiles.getProfilePathFromName(profileName); for (const layer of this.mConfig.layers) { if (lodash.get(layer.properties, profilePath) != null) { return layer; } } } } exports.ConfigLayers = ConfigLayers; //# sourceMappingURL=ConfigLayers.js.map