Skip to content

Commit

Permalink
feat: allow adding property metas to allowedProperties on config
Browse files Browse the repository at this point in the history
  • Loading branch information
Chad Carbert committed Oct 28, 2020
1 parent 7921b00 commit 2a264d3
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 71 deletions.
175 changes: 104 additions & 71 deletions src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

import { keyBy, set } from '@salesforce/kit';
import { Dictionary, ensure, isNumber, isString } from '@salesforce/ts-types';
import { Logger } from '../logger';
import { Crypto } from '../crypto';
import { Messages } from '../messages';
import { SfdxError } from '../sfdxError';
import { sfdc } from '../util/sfdc';
import { ConfigFile } from './configFile';
import { ConfigContents, ConfigValue } from './configStore';

const log = Logger.childFromRoot('core:config');
const SFDX_CONFIG_FILE_NAME = 'sfdx-config.json';

/**
Expand Down Expand Up @@ -106,83 +108,97 @@ export class Config extends ConfigFile<ConfigFile.Options> {
* allows users to override the 10,000 result query limit
*/
public static readonly MAX_QUERY_LIMIT = 'maxQueryLimit';
private static allowedProperties: ConfigPropertyMeta[];
private static messages: Messages;
private static propertyConfigMap: Dictionary<ConfigPropertyMeta>;
private crypto?: Crypto;

public constructor(options?: ConfigFile.Options) {
super(options || Config.getDefaultOptions(false));

if (!Config.messages) {
Config.messages = Messages.loadMessages('@salesforce/core', 'config');
}
private static get propertyConfigMap(): Dictionary<ConfigPropertyMeta> {
return keyBy(Config.allowedProperties, 'key');
}

if (!Config.allowedProperties) {
Config.allowedProperties = [
{
key: 'instanceUrl',
input: {
// If a value is provided validate it otherwise no value is unset.
validator: (value) => value == null || (isString(value) && sfdc.isSalesforceDomain(value)),
failedMessage: Config.messages.getMessage('InvalidInstanceUrl'),
},
private static allowedProperties: ConfigPropertyMeta[] = [
{
key: 'instanceUrl',
input: {
// If a value is provided validate it otherwise no value is unset.
validator: (value) => value == null || (isString(value) && sfdc.isSalesforceDomain(value)),
get failedMessage() {
return 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 || (isString(value) && sfdc.validateApiVersion(value)),
failedMessage: Config.messages.getMessage('InvalidApiVersion'),
},
},
},
{
key: Config.API_VERSION,
hidden: true,
input: {
// If a value is provided validate it otherwise no value is unset.
validator: (value) => value == null || (isString(value) && sfdc.validateApiVersion(value)),
get failedMessage() {
return 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 || isString(value),
failedMessage: Config.messages.getMessage('InvalidIsvDebuggerSid'),
},
},
},
{ 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 || isString(value),
get failedMessage() {
return 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 || isString(value),
failedMessage: Config.messages.getMessage('InvalidIsvDebuggerUrl'),
},
},
},
{
key: Config.ISV_DEBUGGER_URL,
input: {
// If a value is provided validate it otherwise no value is unset.
validator: (value) => value == null || isString(value),
get failedMessage() {
return Config.messages?.getMessage('InvalidIsvDebuggerUrl');
},
{
key: Config.DISABLE_TELEMETRY,
input: {
validator: (value) => value == null || ['true', 'false'].includes(value.toString()),
failedMessage: Config.messages.getMessage('InvalidBooleanConfigValue'),
},
},
},
{
key: Config.DISABLE_TELEMETRY,
input: {
validator: (value) => value == null || ['true', 'false'].includes(value.toString()),
get failedMessage() {
return 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'),
},
},
},
// 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()),
get failedMessage() {
return Config.messages?.getMessage('InvalidBooleanConfigValue');
},
{
key: Config.MAX_QUERY_LIMIT,
input: {
validator: (value) => isNumber(value),
failedMessage: Config.messages.getMessage('InvalidNumberConfigValue'),
},
},
},
{
key: Config.MAX_QUERY_LIMIT,
input: {
validator: (value) => isNumber(value),
get failedMessage() {
return Config.messages?.getMessage('InvalidNumberConfigValue');
},
];
},
},
];

private static messages: Messages;
private crypto?: Crypto;

public constructor(options?: ConfigFile.Options) {
super(options || Config.getDefaultOptions(false));

if (!Config.messages) {
Config.messages = Messages.loadMessages('@salesforce/core', 'config');
}

Config.propertyConfigMap = keyBy(Config.allowedProperties, 'key');
// Resolve the config path on creation.
this.getPath();
}
Expand All @@ -197,15 +213,30 @@ export class Config extends ConfigFile<ConfigFile.Options> {
}

/**
* Returns an object representing the supported allowed properties.
* Returns an array of objects representing the allowed config properties.
*/
public static getAllowedProperties(): ConfigPropertyMeta[] {
if (!Config.allowedProperties) {
throw new SfdxError('Config meta information has not been initialized. Use Config.create()');
}
return Config.allowedProperties;
}

/**
* Add an array of allowed config properties.
*
* @param metas Array of objects to set as the allowed config properties.
*/
public static addAllowedProperties(metas: ConfigPropertyMeta[]): void {
const currentMetaKeys = Object.keys(Config.propertyConfigMap);

metas.forEach((meta) => {
if (currentMetaKeys.includes(meta.key)) {
log.info(`Key ${meta.key} already exists in allowedProperties, skipping.`);
return;
}

Config.allowedProperties.push(meta);
});
}

/**
* Gets default options.
*
Expand Down Expand Up @@ -316,7 +347,9 @@ export class Config extends ConfigFile<ConfigFile.Options> {
if (property.input && property.input.validator(value)) {
super.set(property.key, value);
} else {
throw SfdxError.create('@salesforce/core', 'config', 'InvalidConfigValue', [property.input.failedMessage]);
throw SfdxError.create('@salesforce/core', 'config', 'InvalidConfigValue', [
property.input.failedMessage ?? '',
]);
}
} else {
super.set(property.key, value);
Expand Down
39 changes: 39 additions & 0 deletions test/unit/config/configTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,43 @@ describe('Config', () => {
expect(writeStub.called).to.be.true;
});
});

describe('allowed properties', () => {
let originalAllowedProperties;

beforeEach(() => {
originalAllowedProperties = (Config as any).allowedProperties;
(Config as any).allowedProperties = [];
});

afterEach(() => {
(Config as any).allowedProperties = originalAllowedProperties;
});

it('has default properties assigned', () => {
expect(originalAllowedProperties.length).to.be.greaterThan(0);

expect(
originalAllowedProperties.some((meta) => meta.key === 'instanceUrl'),
'it has one of the default allowed properties'
).to.be.true;
});

it('can add allowed properties', () => {
const configMetas = [
{
key: 'hello',
hidden: false,
encrypted: false,
},
];

Config.addAllowedProperties(configMetas);
const addedConfigMeta = Config.getAllowedProperties().find((configMeta) => configMeta.key === 'hello');

expect(addedConfigMeta.key).to.equal('hello');
expect(addedConfigMeta.hidden).to.equal(false);
expect(addedConfigMeta.encrypted).to.equal(false);
});
});
});

0 comments on commit 2a264d3

Please sign in to comment.