UNPKG

@salesforce/core

Version:

Core libraries to interact with SFDX projects, orgs, and APIs.

329 lines 12 kB
"use strict"; /* * Copyright (c) 2020, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = void 0; const kit_1 = require("@salesforce/kit"); const ts_types_1 = require("@salesforce/ts-types"); const crypto_1 = require("../crypto"); const messages_1 = require("../messages"); const sfdxError_1 = require("../sfdxError"); const sfdc_1 = require("../util/sfdc"); const configFile_1 = require("./configFile"); const SFDX_CONFIG_FILE_NAME = 'sfdx-config.json'; /** * The files where sfdx config values are stored for projects and the global space. * * *Note:* It is not recommended to instantiate this object directly when resolving * config values. Instead use {@link ConfigAggregator} * * ``` * const localConfig = await Config.create({}); * localConfig.set('defaultusername', 'username@company.org'); * await localConfig.write(); * ``` * https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_cli_config_values.htm */ class Config extends configFile_1.ConfigFile { constructor(options) { super(options || Config.getDefaultOptions(false)); if (!Config.messages) { Config.messages = messages_1.Messages.loadMessages('@salesforce/core', 'config'); } if (!Config.allowedProperties) { Config.allowedProperties = [ { key: 'instanceUrl', input: { // If a value is provided validate it otherwise no value is unset. validator: (value) => value == null || (ts_types_1.isString(value) && sfdc_1.sfdc.isSalesforceDomain(value)), failedMessage: Config.messages.getMessage('InvalidInstanceUrl'), }, }, { key: Config.API_VERSION, hidden: true, input: { // If a value is provided validate it otherwise no value is unset. validator: (value) => value == null || (ts_types_1.isString(value) && sfdc_1.sfdc.validateApiVersion(value)), failedMessage: Config.messages.getMessage('InvalidApiVersion'), }, }, { key: Config.DEFAULT_DEV_HUB_USERNAME }, { key: Config.DEFAULT_USERNAME }, { key: Config.ISV_DEBUGGER_SID, encrypted: true, input: { // If a value is provided validate it otherwise no value is unset. validator: (value) => value == null || ts_types_1.isString(value), failedMessage: Config.messages.getMessage('InvalidIsvDebuggerSid'), }, }, { key: Config.ISV_DEBUGGER_URL, input: { // If a value is provided validate it otherwise no value is unset. validator: (value) => value == null || ts_types_1.isString(value), failedMessage: Config.messages.getMessage('InvalidIsvDebuggerUrl'), }, }, { key: Config.DISABLE_TELEMETRY, input: { validator: (value) => value == null || ['true', 'false'].includes(value.toString()), failedMessage: Config.messages.getMessage('InvalidBooleanConfigValue'), }, }, // This should be brought in by a plugin, but there isn't a way to do that right now. { key: 'restDeploy', hidden: true, input: { validator: (value) => value != null && ['true', 'false'].includes(value.toString()), failedMessage: Config.messages.getMessage('InvalidBooleanConfigValue'), }, }, { key: Config.MAX_QUERY_LIMIT, input: { validator: (value) => ts_types_1.isNumber(value), failedMessage: Config.messages.getMessage('InvalidNumberConfigValue'), }, }, ]; } Config.propertyConfigMap = kit_1.keyBy(Config.allowedProperties, 'key'); // Resolve the config path on creation. this.getPath(); } /** * Returns the default file name for a config file. * * **See** {@link SFDX_CONFIG_FILE_NAME} */ static getFileName() { return SFDX_CONFIG_FILE_NAME; } /** * Returns an object representing the supported allowed properties. */ static getAllowedProperties() { if (!Config.allowedProperties) { throw new sfdxError_1.SfdxError('Config meta information has not been initialized. Use Config.create()'); } return Config.allowedProperties; } /** * Gets default options. * * @param isGlobal Make the config global. * @param filename Override the default file. {@link Config.getFileName} */ static getDefaultOptions(isGlobal = false, filename) { return { isGlobal, isState: true, filename: filename || this.getFileName(), }; } /** * The value of a supported config property. * * @param isGlobal True for a global config. False for a local config. * @param propertyName The name of the property to set. * @param value The property value. */ static async update(isGlobal, propertyName, value) { const config = await Config.create(Config.getDefaultOptions(isGlobal)); const content = await config.read(); if (value == null) { delete content[propertyName]; } else { kit_1.set(content, propertyName, value); } return config.write(content); } /** * Clear all the configured properties both local and global. */ static async clear() { let config = await Config.create(Config.getDefaultOptions(true)); config.clear(); await config.write(); config = await Config.create(Config.getDefaultOptions(false)); config.clear(); await config.write(); } /** * Read, assign, and return the config contents. */ async read(force = true) { try { await super.read(false, force); await this.cryptProperties(false); return this.getContents(); } finally { await this.clearCrypto(); } } /** * Writes Config properties taking into account encrypted properties. * * @param newContents The new Config value to persist. */ async write(newContents) { if (newContents != null) { this.setContents(newContents); } await this.cryptProperties(true); await super.write(); await this.cryptProperties(false); return this.getContents(); } /** * DO NOT CALL - The config file needs to encrypt values which can only be done asynchronously. * Call {@link SfdxConfig.write} instead. * * **Throws** *{@link SfdxError}{ name: 'InvalidWrite' }* Always. * * @param newContents Contents to write */ // eslint-disable-next-line @typescript-eslint/no-unused-vars writeSync(newContents) { throw sfdxError_1.SfdxError.create('@salesforce/core', 'config', 'InvalidWrite'); } /** * Sets a value for a property. * * **Throws** *{@link SfdxError}{ name: 'InvalidConfigValue' }* If the input validator fails. * * @param key The property to set. * @param value The value of the property. */ set(key, value) { const property = Config.allowedProperties.find((allowedProp) => allowedProp.key === key); if (!property) { throw sfdxError_1.SfdxError.create('@salesforce/core', 'config', 'UnknownConfigKey', [key]); } if (property.input) { if (property.input && property.input.validator(value)) { super.set(property.key, value); } else { throw sfdxError_1.SfdxError.create('@salesforce/core', 'config', 'InvalidConfigValue', [property.input.failedMessage]); } } else { super.set(property.key, value); } return this.getContents(); } /** * Unsets a value for a property. * * **Throws** *{@link SfdxError}{ name: 'UnknownConfigKey' }* If the input validator fails. * * @param key The property to unset. */ unset(key) { const property = Config.allowedProperties.find((allowedProp) => allowedProp.key === key); if (!property) { throw sfdxError_1.SfdxError.create('@salesforce/core', 'config', 'UnknownConfigKey', [key]); } return super.unset(property.key); } /** * Initializer for supported config types. */ async init() { // Super ConfigFile calls read, which has a dependency on crypto, which finally has a dependency on // Config.propertyConfigMap being set. This is why init is called after the setup. await super.init(); } /** * Initialize the crypto dependency. */ async initCrypto() { if (!this.crypto) { this.crypto = await crypto_1.Crypto.create(); } } /** * Closes the crypto dependency. Crypto should be close after it's used and no longer needed. */ // eslint-disable-next-line @typescript-eslint/require-await async clearCrypto() { if (this.crypto) { this.crypto.close(); delete this.crypto; } } /** * Get an individual property config. * * @param propertyName The name of the property. */ getPropertyConfig(propertyName) { const prop = Config.propertyConfigMap[propertyName]; if (!prop) { throw sfdxError_1.SfdxError.create('@salesforce/core', 'config', 'UnknownConfigKey', [propertyName]); } return prop; } /** * Encrypts and content properties that have a encryption attribute. * * @param encrypt `true` to encrypt. */ async cryptProperties(encrypt) { const hasEncryptedProperties = this.entries().some(([key]) => { return !!ts_types_1.ensure(Config.propertyConfigMap[key]).encrypted; }); if (hasEncryptedProperties) { await this.initCrypto(); const crypto = ts_types_1.ensure(this.crypto); this.forEach((key, value) => { if (this.getPropertyConfig(key).encrypted && ts_types_1.isString(value)) { this.set(key, ts_types_1.ensure(encrypt ? crypto.encrypt(value) : crypto.decrypt(value))); } }); } } } exports.Config = Config; /** * Username associated with the default dev hub org. */ Config.DEFAULT_DEV_HUB_USERNAME = 'defaultdevhubusername'; /** * Username associate with the default org. */ Config.DEFAULT_USERNAME = 'defaultusername'; /** * The sid for the debugger configuration. */ Config.ISV_DEBUGGER_SID = 'isvDebuggerSid'; /** * The url for the debugger configuration. */ Config.ISV_DEBUGGER_URL = 'isvDebuggerUrl'; /** * The api version */ Config.API_VERSION = 'apiVersion'; /** * Disables telemetry reporting */ Config.DISABLE_TELEMETRY = 'disableTelemetry'; /** * allows users to override the 10,000 result query limit */ Config.MAX_QUERY_LIMIT = 'maxQueryLimit'; //# sourceMappingURL=config.js.map