diff --git a/src/config/configStore.ts b/src/config/configStore.ts
index 010f1ea2c..70a9913f9 100644
--- a/src/config/configStore.ts
+++ b/src/config/configStore.ts
@@ -20,7 +20,9 @@ import { ConfigContents, ConfigEntry, ConfigValue, Key } from './configStackType
export interface ConfigStore
{
// Map manipulation methods
entries(): ConfigEntry[];
+ // NEXT_RELEASE: update types to specify return can be P[K] | undefined
get>(key: K, decrypt: boolean): P[K];
+ // NEXT_RELEASE: update types to specify return can be T | undefined
get(key: string, decrypt: boolean): T;
getKeysByValue(value: ConfigValue): Array>;
has(key: string): boolean;
@@ -88,8 +90,12 @@ export abstract class BaseConfigStore<
* @param decrypt If it is an encrypted key, decrypt the value.
* If the value is an object, a clone will be returned.
*/
+ // NEXT_RELEASE: update types to specify return can be | undefined
public get>(key: K, decrypt?: boolean): P[K];
+ // NEXT_RELEASE: update types to specify return can be | undefined
+ // NEXT_RELEASE: consider getting rid of ConfigValue and letting it just use the Key<> approach
public get(key: string, decrypt?: boolean): V;
+ // NEXT_RELEASE: update types to specify return can be | undefined
public get>(key: K | string, decrypt = false): P[K] | ConfigValue {
const rawValue = this.contents.get(key as K);
@@ -100,6 +106,7 @@ export abstract class BaseConfigStore<
return this.decrypt(rawValue) as P[K] | ConfigValue;
}
}
+ // NEXT_RELEASE: update types to specify return can be | undefined
return rawValue as P[K] | ConfigValue;
}
diff --git a/src/org/scratchOrgCreate.ts b/src/org/scratchOrgCreate.ts
index 414a8fcc9..4a09a6e28 100644
--- a/src/org/scratchOrgCreate.ts
+++ b/src/org/scratchOrgCreate.ts
@@ -110,9 +110,12 @@ export const scratchOrgResume = async (jobId: string): Promise {
const config = new TestConfig<{ '1': { a: string } }>();
config.set('1', { a: 'a' });
- config.get('1').a = 'b';
+ config.get('1')!.a = 'b';
- expect(config.get('1').a).to.equal('b');
+ expect(config.get('1')!.a).to.equal('b');
});
it('updates the object reference', async () => {
@@ -64,8 +64,13 @@ describe('ConfigStore', () => {
config.update('1', { b: 'c' });
- expect(config.get('1').a).to.equal('a');
- expect(config.get('1').b).to.equal('c');
+ expect(config.get('1')!.a).to.equal('a');
+ expect(config.get('1')!.b).to.equal('c');
+ });
+
+ it('undefined keys return undefined', async () => {
+ const config = new TestConfig<{ '1': { a: string } }>();
+ expect(config.get('not-a-thing')).to.equal(undefined);
});
describe('encryption', () => {
@@ -111,9 +116,9 @@ describe('ConfigStore', () => {
});
const owner = config.get('owner');
// encrypted
- expect(owner.creditCardNumber).to.not.equal(expected);
+ expect(owner?.creditCardNumber).to.not.equal(expected);
// decrypted
- expect(config.get('owner', true).creditCardNumber).to.equal(expected);
+ expect(config.get('owner', true)?.creditCardNumber).to.equal(expected);
});
it('encrypts nested key using regexp', async () => {
@@ -129,9 +134,9 @@ describe('ConfigStore', () => {
});
const owner = config.get('owner');
// encrypted
- expect(owner.superPassword).to.not.equal(expected);
+ expect(owner?.superPassword).to.not.equal(expected);
// decrypted
- expect(config.get('owner', true).superPassword).to.equal(expected);
+ expect(config.get('owner', true)?.superPassword).to.equal(expected);
});
it('decrypt returns copies', async () => {
@@ -142,11 +147,12 @@ describe('ConfigStore', () => {
config.set('owner', owner);
const decryptedOwner = config.get('owner', true);
+ assert(decryptedOwner);
// Because we retrieved an decrypted object on a config with encryption,
// it should return a clone so it doesn't accidentally save decrypted data.
decryptedOwner.creditCardNumber = 'invalid';
- expect(config.get('owner').creditCardNumber).to.not.equal('invalid');
- expect(config.get('owner', true).creditCardNumber).to.equal(expected);
+ expect(config.get('owner')?.creditCardNumber).to.not.equal('invalid');
+ expect(config.get('owner', true)?.creditCardNumber).to.equal(expected);
});
// Ensures accessToken and refreshToken are both decrypted upon config.get()
@@ -170,13 +176,13 @@ describe('ConfigStore', () => {
const owner = { name: 'Bob', creditCardNumber: expected };
// @ts-expect-error incomplete owner
config.set('owner', owner);
- const encryptedCreditCardNumber = config.get('owner').creditCardNumber;
+ const encryptedCreditCardNumber = config.get('owner')?.creditCardNumber;
const contents = config.getContents();
contents.owner.name = 'Tim';
// @ts-expect-error private method
config.setContents(contents);
- expect(config.get('owner').name).to.equal(contents.owner.name);
- expect(config.get('owner').creditCardNumber).to.equal(encryptedCreditCardNumber);
+ expect(config.get('owner')?.name).to.equal(contents.owner.name);
+ expect(config.get('owner')?.creditCardNumber).to.equal(encryptedCreditCardNumber);
});
it('updates encrypted object', async () => {
@@ -188,8 +194,8 @@ describe('ConfigStore', () => {
config.update('owner', { creditCardNumber: expected });
- expect(config.get('owner').name).to.equal(owner.name);
- expect(config.get('owner', true).creditCardNumber).to.equal(expected);
+ expect(config.get('owner')?.name).to.equal(owner.name);
+ expect(config.get('owner', true)?.creditCardNumber).to.equal(expected);
});
});
});
diff --git a/test/unit/config/ttlConfigTest.ts b/test/unit/config/ttlConfigTest.ts
index 59bf3823e..144b5bd8d 100644
--- a/test/unit/config/ttlConfigTest.ts
+++ b/test/unit/config/ttlConfigTest.ts
@@ -85,14 +85,14 @@ describe('TTLConfig', () => {
it('should return true if timestamp is older than TTL', async () => {
const config = await TestConfig.create();
config.set('1', { one: 'one' });
- const isExpired = config.isExpired(new Date().getTime() + Duration.days(7).milliseconds, config.get('1'));
+ const isExpired = config.isExpired(new Date().getTime() + Duration.days(7).milliseconds, config.get('1')!);
expect(isExpired).to.be.true;
});
it('should return false if timestamp is not older than TTL', async () => {
const config = await TestConfig.create();
config.set('1', { one: 'one' });
- const isExpired = config.isExpired(new Date().getTime(), config.get('1'));
+ const isExpired = config.isExpired(new Date().getTime(), config.get('1')!);
expect(isExpired).to.be.false;
});
});