From 95fb19e7abf3eb5f1fb2146a7dad09d652879342 Mon Sep 17 00:00:00 2001 From: Chris Lample Date: Fri, 9 Jun 2023 12:08:47 +0200 Subject: [PATCH] fix: lazily initialize config file (#762) --- .../cli/src/services/__tests__/config.spec.ts | 13 ++++ packages/cli/src/services/config.ts | 59 +++++++++++-------- 2 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 packages/cli/src/services/__tests__/config.spec.ts diff --git a/packages/cli/src/services/__tests__/config.spec.ts b/packages/cli/src/services/__tests__/config.spec.ts new file mode 100644 index 00000000..4238f1f7 --- /dev/null +++ b/packages/cli/src/services/__tests__/config.spec.ts @@ -0,0 +1,13 @@ +import Conf from 'conf' +import config from '../config' +jest.mock('conf') + +describe('config', () => { + it('should avoid reading config file if environment variables are set', () => { + process.env.CHECKLY_API_KEY = 'test-api-key' + const apiKey = config.getApiKey() + expect(apiKey).toEqual(process.env.CHECKLY_API_KEY) + expect(Conf).toHaveBeenCalledTimes(0) + delete process.env.CHECKLY_API_KEY + }) +}) diff --git a/packages/cli/src/services/config.ts b/packages/cli/src/services/config.ts index 816fde90..083833b3 100644 --- a/packages/cli/src/services/config.ts +++ b/packages/cli/src/services/config.ts @@ -19,26 +19,38 @@ enum Env { local = 'local', } -const config = { - auth: new Conf({ - projectName: '@checkly/cli', - configName: 'auth', - projectSuffix, - // @ts-ignore - schema: authSchema, - }), - data: new Conf({ - projectName: '@checkly/cli', - configName: 'config', - projectSuffix, - // @ts-ignore - schema: dataSchema, - }), +class ChecklyConfig { + private _auth?: Conf<{ apiKey: unknown }> + private _data?: Conf<{ accountId: unknown, accountName: unknown }> + + // Accessing auth or data will cause a config file to be created. + // We should avoid doing this unless absolutely necessary, since this operation can fail due to file permissions. + get auth () { + // Create this._auth lazily + return this._auth ?? (this._auth = new Conf({ + projectName: '@checkly/cli', + configName: 'auth', + projectSuffix, + // @ts-ignore + schema: authSchema, + })) + } + + get data () { + // Create this._data lazily + return this._data ?? (this._data = new Conf({ + projectName: '@checkly/cli', + configName: 'config', + projectSuffix, + // @ts-ignore + schema: dataSchema, + })) + } clear () { this.auth.clear() this.data.clear() - }, + } getEnv (): Env { const environments = ['production', 'development', 'staging', 'local'] @@ -49,21 +61,21 @@ const config = { } return env as Env - }, + } getApiKey (): string { return process.env.CHECKLY_API_KEY || this.auth.get('apiKey') as string || '' - }, + } getAccountId (): string { return process.env.CHECKLY_ACCOUNT_ID || this.data.get('accountId') as string || '' - }, + } hasEnvVarsConfigured (): boolean { const apiKey = process.env.CHECKLY_API_KEY || '' const accoundId = process.env.CHECKLY_ACCOUNT_ID || '' return apiKey !== '' || accoundId !== '' - }, + } getApiUrl (): string { const environments = { @@ -73,7 +85,7 @@ const config = { production: 'https://api.checklyhq.com', } return environments[this.getEnv()]! - }, + } getMqttUrl (): string { const environments = { @@ -83,14 +95,15 @@ const config = { production: 'wss://events.checklyhq.com', } return environments[this.getEnv()]! - }, + } hasValidCredentials (): boolean { if (this.getApiKey() !== '' && this.getAccountId() !== '') { return true } return false - }, + } } +const config = new ChecklyConfig() export default config