minor refactoring and more config util assertions

This commit is contained in:
William Welling
2021-12-07 21:33:43 -06:00
parent 18dd2ad884
commit bc999d0b5f
3 changed files with 80 additions and 17 deletions

View File

@@ -11,8 +11,6 @@ import { isNotEmpty } from '../app/shared/empty.util';
const CONFIG_PATH = join(process.cwd(), 'config'); const CONFIG_PATH = join(process.cwd(), 'config');
const APP_CONFIG_PATH = join(CONFIG_PATH, 'appConfig.json');
type Environment = 'production' | 'development' | 'test'; type Environment = 'production' | 'development' | 'test';
const getBooleanFromString = (variable: string): boolean => { const getBooleanFromString = (variable: string): boolean => {
@@ -47,7 +45,7 @@ const getEnvironment = (): Environment => {
const getLocalConfigPath = (env: Environment) => { const getLocalConfigPath = (env: Environment) => {
// default to config/appConfig.json // default to config/appConfig.json
let localConfigPath = APP_CONFIG_PATH; let localConfigPath = join(CONFIG_PATH, 'appConfig.json');
// determine app config filename variations // determine app config filename variations
let envVariations; let envVariations;
@@ -65,9 +63,9 @@ const getLocalConfigPath = (env: Environment) => {
// check if any environment variations of app config exist // check if any environment variations of app config exist
for (const envVariation of envVariations) { for (const envVariation of envVariations) {
const altDistConfigPath = join(CONFIG_PATH, `appConfig.${envVariation}.json`); const envLocalConfigPath = join(CONFIG_PATH, `appConfig.${envVariation}.json`);
if (fs.existsSync(altDistConfigPath)) { if (fs.existsSync(envLocalConfigPath)) {
localConfigPath = altDistConfigPath; localConfigPath = envLocalConfigPath;
} }
} }
@@ -106,7 +104,6 @@ const overrideWithEnvironment = (config: Config, key: string = '') => {
default: default:
console.warn(`Unsupported environment variable type ${typeof innerConfig} ${variable}`); console.warn(`Unsupported environment variable type ${typeof innerConfig} ${variable}`);
} }
} }
} }
} }
@@ -122,6 +119,16 @@ const buildBaseUrl = (config: ServerConfig): void => {
].join(''); ].join('');
}; };
/**
* Build app config with the following chain of override.
*
* local config -> environment local config -> external config -> environment variable
*
* Optionally save to file.
*
* @param destConfigPath optional path to save config file
* @returns app config
*/
export const buildAppConfig = (destConfigPath?: string): AppConfig => { export const buildAppConfig = (destConfigPath?: string): AppConfig => {
// start with default app config // start with default app config
const appConfig: AppConfig = new DefaultAppConfig(); const appConfig: AppConfig = new DefaultAppConfig();
@@ -141,11 +148,11 @@ export const buildAppConfig = (destConfigPath?: string): AppConfig => {
} }
// override with dist config // override with dist config
const distConfigPath = getLocalConfigPath(env); const localConfigPath = getLocalConfigPath(env);
if (fs.existsSync(distConfigPath)) { if (fs.existsSync(localConfigPath)) {
overrideWithConfig(appConfig, distConfigPath); overrideWithConfig(appConfig, localConfigPath);
} else { } else {
console.warn(`Unable to find dist config file at ${distConfigPath}`); console.warn(`Unable to find dist config file at ${localConfigPath}`);
} }
// override with external config if specified by environment variable `APP_CONFIG_PATH` // override with external config if specified by environment variable `APP_CONFIG_PATH`

View File

@@ -1,17 +1,56 @@
import { environment } from '../environments/environment.prod'; import { environment } from '../environments/environment.prod';
import { extendEnvironmentWithAppConfig } from './config.util'; import { extendEnvironmentWithAppConfig } from './config.util';
import { DefaultAppConfig } from './default-app-config'; import { DefaultAppConfig } from './default-app-config';
import { HandleThemeConfig } from './theme.model';
describe('Config Util', () => { describe('Config Util', () => {
describe('extendEnvironmentWithAppConfig', () => { describe('extendEnvironmentWithAppConfig', () => {
it('should extend prod environment with app config', () => { it('should extend prod environment with app config', () => {
const appConfig = new DefaultAppConfig(); const appConfig = new DefaultAppConfig();
const originalMsToLive = appConfig.cache.msToLive.default; expect(appConfig.cache.msToLive.default).toEqual(15 * 60 * 1000); // 15 minute
expect(originalMsToLive).toEqual(15 * 60 * 1000); // 15 minute expect(appConfig.ui.rateLimiter.windowMs).toEqual(1 * 60 * 1000); // 1 minute
expect(appConfig.ui.rateLimiter.max).toEqual(500);
expect(appConfig.submission.autosave.metadata).toEqual([]);
expect(appConfig.themes.length).toEqual(1);
expect(appConfig.themes[0].name).toEqual('dspace');
const msToLive = 1 * 60 * 1000; // 1 minute const msToLive = 1 * 60 * 1000; // 1 minute
appConfig.cache.msToLive.default = msToLive; appConfig.cache.msToLive.default = msToLive;
const rateLimiter = {
windowMs: 5 * 50 * 1000, // 5 minutes
max: 1000
};
appConfig.ui.rateLimiter = rateLimiter;
const autoSaveMetadata = [
'dc.author',
'dc.title'
];
appConfig.submission.autosave.metadata = autoSaveMetadata;
const customTheme: HandleThemeConfig = {
name: 'custom',
handle: '10673/1233'
};
appConfig.themes.push(customTheme);
extendEnvironmentWithAppConfig(environment, appConfig); extendEnvironmentWithAppConfig(environment, appConfig);
expect(environment.cache.msToLive.default).toEqual(msToLive); expect(environment.cache.msToLive.default).toEqual(msToLive);
expect(environment.ui.rateLimiter.windowMs).toEqual(rateLimiter.windowMs);
expect(environment.ui.rateLimiter.max).toEqual(rateLimiter.max);
expect(environment.submission.autosave.metadata[0]).toEqual(autoSaveMetadata[0]);
expect(environment.submission.autosave.metadata[1]).toEqual(autoSaveMetadata[1]);
expect(environment.themes.length).toEqual(2);
expect(environment.themes[0].name).toEqual('dspace');
expect(environment.themes[1].name).toEqual(customTheme.name);
expect((environment.themes[1] as HandleThemeConfig).handle).toEqual(customTheme.handle);
}); });
}); });
}); });

View File

@@ -7,21 +7,38 @@ import { hasNoValue } from '../app/shared/empty.util';
import { AppConfig } from './app-config.interface'; import { AppConfig } from './app-config.interface';
import { ThemeConfig } from './theme.model'; import { ThemeConfig } from './theme.model';
/**
* Extend Angular environment with app config.
*
* @param env environment object
* @param appConfig app config
*/
const extendEnvironmentWithAppConfig = (env: any, appConfig: AppConfig): void => { const extendEnvironmentWithAppConfig = (env: any, appConfig: AppConfig): void => {
mergeConfig(env, appConfig); mergeConfig(env, appConfig);
console.log(`Environment extended with app config`); console.log(`Environment extended with app config`);
}; };
const mergeConfig = (config: any, appConfig: AppConfig): void => { /**
* Merge one config into another.
*
* @param destinationConfig destination config
* @param sourceConfig source config
*/
const mergeConfig = (destinationConfig: any, sourceConfig: AppConfig): void => {
const mergeOptions = { const mergeOptions = {
arrayMerge: (destinationArray, sourceArray, options) => sourceArray arrayMerge: (destinationArray, sourceArray, options) => sourceArray
}; };
Object.assign(config, merge.all([ Object.assign(destinationConfig, merge.all([
config, destinationConfig,
appConfig sourceConfig
], mergeOptions)); ], mergeOptions));
}; };
/**
* Get default them config from environment.
*
* @returns default theme config
*/
const getDefaultThemeConfig = (): ThemeConfig => { const getDefaultThemeConfig = (): ThemeConfig => {
return environment.themes.find((themeConfig: any) => return environment.themes.find((themeConfig: any) =>
hasNoValue(themeConfig.regex) && hasNoValue(themeConfig.regex) &&