From ae033903317d9a3bd229b564449c5ec61fe6eeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Wed, 13 Oct 2021 20:52:44 +0200 Subject: [PATCH] fix: add support for experimental flags (#1025) --- .../__snapshots__/create-config.test.ts.snap | 81 +++++++++++++++++++ src/lib/create-config.test.ts | 66 +++++++++++++++ src/lib/create-config.ts | 41 ++++++++-- src/lib/types/option.ts | 17 +++- 4 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 src/lib/__snapshots__/create-config.test.ts.snap create mode 100644 src/lib/create-config.test.ts diff --git a/src/lib/__snapshots__/create-config.test.ts.snap b/src/lib/__snapshots__/create-config.test.ts.snap new file mode 100644 index 0000000000..1f128f1e8c --- /dev/null +++ b/src/lib/__snapshots__/create-config.test.ts.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should create default config 1`] = ` +Object { + "authentication": Object { + "createAdminUser": true, + "customAuthHandler": [Function], + "enableApiToken": true, + "type": "open-source", + }, + "db": Object { + "acquireConnectionTimeout": 30000, + "database": "unleash_db", + "disableMigration": false, + "driver": "postgres", + "host": "localhost", + "password": "password", + "pool": Object { + "idleTimeoutMillis": 30000, + "max": 4, + "min": 0, + "propagateCreateError": false, + }, + "port": 4242, + "schema": "public", + "ssl": Object { + "rejectUnauthorized": false, + }, + "user": "unleash", + "version": undefined, + }, + "email": Object { + "host": undefined, + "port": 587, + "secure": false, + "sender": "noreply@unleash-hosted.com", + "smtppass": undefined, + "smtpuser": undefined, + }, + "enableOAS": false, + "enterpriseVersion": undefined, + "eventHook": undefined, + "experimental": Object {}, + "getLogger": [Function], + "import": Object { + "dropBeforeImport": false, + "file": undefined, + "keepExisting": false, + }, + "listen": Object { + "host": undefined, + "port": 4242, + }, + "preHook": undefined, + "preRouterHook": undefined, + "secureHeaders": false, + "server": Object { + "baseUriPath": "", + "enableRequestLogger": false, + "gracefulShutdownEnable": true, + "gracefulShutdownTimeout": 1000, + "headersTimeout": 61000, + "host": undefined, + "keepAliveTimeout": 60000, + "pipe": undefined, + "port": 4242, + "secret": "super-secret", + "serverMetrics": true, + "unleashUrl": "http://localhost:4242", + }, + "session": Object { + "db": true, + "ttlHours": 48, + }, + "ui": Object {}, + "versionCheck": Object { + "enable": true, + "url": "https://version.unleash.run", + }, +} +`; diff --git a/src/lib/create-config.test.ts b/src/lib/create-config.test.ts new file mode 100644 index 0000000000..ff5eb185ea --- /dev/null +++ b/src/lib/create-config.test.ts @@ -0,0 +1,66 @@ +// @ts-nocheck +import { createConfig } from './create-config'; + +test('should create default config', async () => { + const config = createConfig({ + db: { + host: 'localhost', + port: 4242, + user: 'unleash', + password: 'password', + database: 'unleash_db', + }, + server: { + port: 4242, + }, + }); + + expect(config).toMatchSnapshot(); +}); + +test('should enabled metricsV2 via options', async () => { + const config = createConfig({ + experimental: { + metricsV2: { enabled: true }, + }, + }); + + expect(config.experimental.metricsV2.enabled).toBe(true); +}); + +test('should enabled metricsV2 via env variable', async () => { + process.env.EXP_METRICS_V2 = 'true'; + const config = createConfig({}); + + expect(config.experimental.metricsV2.enabled).toBe(true); + delete process.env.EXP_METRICS_V2; +}); + +test('should enabled metricsV2 when environments is enabled via env variable', async () => { + process.env.EXP_ENVIRONMENTS = 'true'; + const config = createConfig({}); + + expect(config.experimental.environments.enabled).toBe(true); + expect(config.experimental.metricsV2.enabled).toBe(true); + delete process.env.EXP_ENVIRONMENTS; +}); + +test('should enabled metricsV2 when environments is enabled via options', async () => { + const config = createConfig({ + experimental: { + environments: { enabled: true }, + }, + }); + + expect(config.experimental.environments.enabled).toBe(true); + expect(config.experimental.metricsV2.enabled).toBe(true); +}); + +test('should set UI flag when environments is enabled', async () => { + process.env.EXP_ENVIRONMENTS = 'true'; + const config = createConfig({}); + + expect(config.experimental.environments.enabled).toBe(true); + expect(config.ui.flags?.E).toBe(true); + delete process.env.EXP_ENVIRONMENTS; +}); diff --git a/src/lib/create-config.ts b/src/lib/create-config.ts index 6704cc34e9..3d34d599c2 100644 --- a/src/lib/create-config.ts +++ b/src/lib/create-config.ts @@ -14,6 +14,7 @@ import { IEmailOption, IListeningPipe, IListeningHost, + IUIConfig, } from './types/option'; import { getDefaultLogProvider, LogLevel, validateLogProvider } from './logger'; import { defaultCustomAuthDenyAll } from './default-custom-auth-deny-all'; @@ -51,6 +52,36 @@ function mergeAll(objects: Partial[]): T { return merge.all(objects.filter((i) => i)); } +function loadExperimental(options: IUnleashOptions): any { + const experimental = options.experimental || {}; + + if (safeBoolean(process.env.EXP_ENVIRONMENTS, false)) { + experimental.environments = { enabled: true }; + } + + if ( + safeBoolean(process.env.EXP_METRICS_V2, false) || + //@ts-ignore + experimental.environments?.enabled + ) { + experimental.metricsV2 = { enabled: true }; + } + + return experimental; +} + +function loadUI(options: IUnleashOptions, experimental: any = {}): IUIConfig { + const uiO = options.ui || {}; + const ui: IUIConfig = {}; + + if (experimental.environments?.enabled) { + ui.flags = { + E: true, + }; + } + return mergeAll([uiO, ui]); +} + const defaultDbOptions: IDBOption = { user: process.env.DATABASE_USERNAME, password: process.env.DATABASE_PASSWORD, @@ -215,18 +246,14 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig { : options.authentication, ]); - const ui = options.ui || {}; - const importSetting: IImportOption = mergeAll([ defaultImport, options.import, ]); - const experimental = options.experimental || {}; + const experimental = loadExperimental(options); - if (safeBoolean(process.env.EXP_METRICS_V2, false)) { - experimental.metricsV2 = { enabled: true }; - } + const ui = loadUI(options, experimental); const email: IEmailOption = mergeAll([defaultEmail, options.email]); @@ -253,7 +280,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig { authentication, ui, import: importSetting, - experimental: experimental || {}, + experimental, email, secureHeaders, enableOAS, diff --git a/src/lib/types/option.ts b/src/lib/types/option.ts index fafcd12637..ee50b35a90 100644 --- a/src/lib/types/option.ts +++ b/src/lib/types/option.ts @@ -111,11 +111,26 @@ export interface IEmailOption { export interface IListeningPipe { path: string; } + export interface IListeningHost { host?: string; port: number; } +export interface IUIConfig { + slogan?: string; + name?: string; + flags?: { [key: string]: boolean }; + links?: [ + { + value: string; + icon?: string; + href: string; + title: string; + }, + ]; +} + export interface IUnleashConfig { db: IDBOption; session: ISessionOption; @@ -124,7 +139,7 @@ export interface IUnleashConfig { listen: IListeningHost | IListeningPipe; versionCheck: IVersionOption; authentication: IAuthOption; - ui: object; + ui: IUIConfig; import: IImportOption; experimental: { [key: string]: object;