@salesforce/plugin-settings
Version:
configure the Salesforce CLI
115 lines • 5.28 kB
JavaScript
/*
* Copyright 2025, Salesforce, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { parseVarArgs, Flags, loglevel, Ux, SfCommand } from '@salesforce/sf-plugins-core';
import { Config, Messages, Org, SfError, OrgConfigProperties } from '@salesforce/core';
import { CONFIG_HELP_SECTION, buildFailureMsg, calculateSuggestion, output } from '../../config.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-settings', 'config.set');
export class Set extends SfCommand {
static description = messages.getMessage('description');
static summary = messages.getMessage('summary');
static examples = messages.getMessages('examples');
static aliases = ['force:config:set'];
static deprecateAliases = true;
static strict = false;
static flags = {
loglevel,
global: Flags.boolean({
char: 'g',
summary: messages.getMessage('flags.global.summary'),
}),
};
static configurationVariablesSection = CONFIG_HELP_SECTION;
async run() {
const { args, argv, flags } = await this.parse(Set);
const config = await loadConfig(flags.global);
const responses = { successes: [], failures: [] };
if (!argv.length)
throw messages.createError('error.ArgumentsRequired');
const parsed = parseVarArgs(args, argv);
for (const [name, value] of Object.entries(parsed)) {
let resolvedName = name;
try {
// this needs to be inside the try/catch because it can throw an error
resolvedName = this.configAggregator.getPropertyMeta(name)?.newKey ?? name;
if (!value) {
// Push a failure if users are try to unset a value with `set=`.
responses.failures.push(buildFailureMsg(name, messages.createError('error.ValueRequired'), value));
}
else {
// core's builtin config validation requires synchronous functions but there's
// currently no way to validate an org synchronously. Therefore, we have to manually
// validate the org here and manually set the error message if it fails
// eslint-disable-next-line no-await-in-loop
if (isOrgKey(resolvedName) && value)
await validateOrg(value);
config.set(resolvedName, value);
responses.successes.push({ name: resolvedName, value, success: true });
}
}
catch (error) {
if (error instanceof Error && error.name.includes('UnknownConfigKeyError')) {
if (this.jsonEnabled()) {
responses.failures.push(buildFailureMsg(resolvedName, error, value));
}
else {
const suggestion = calculateSuggestion(name);
// eslint-disable-next-line no-await-in-loop
const answer = (await this.confirm({ message: messages.getMessage('didYouMean', [suggestion]) })) ?? false;
if (answer && value) {
const key = Config.getPropertyConfigMeta(suggestion)?.key ?? suggestion;
config.set(key, value);
responses.successes.push({ name: key, value, success: true });
}
}
}
else {
responses.failures.push(buildFailureMsg(resolvedName, error, value));
}
}
}
await config.write();
if (responses.failures.length) {
process.exitCode = 1;
}
output(new Ux({ jsonEnabled: this.jsonEnabled() }), [...responses.successes, ...responses.failures], 'set');
return responses;
}
}
const loadConfig = async (global) => {
try {
const config = await Config.create(Config.getDefaultOptions(global));
await config.read();
return config;
}
catch (error) {
if (error instanceof SfError) {
error.actions = error.actions ?? [];
error.actions.push('Run with --global to set for your entire workspace.');
}
throw error;
}
};
const isOrgKey = (name) => [OrgConfigProperties.TARGET_DEV_HUB, OrgConfigProperties.TARGET_ORG].includes(name);
const validateOrg = async (value) => {
try {
await Org.create({ aliasOrUsername: value });
}
catch {
throw new Error(`Invalid config value: org "${value}" is not authenticated.`);
}
};
//# sourceMappingURL=set.js.map