import merge from 'lodash.merge'; import cloneDeep from 'lodash.clonedeep'; import type Configuration from '../Contracts/Configuration'; type WithProperty = T & { [P in K]: Exclude

}; export default class GlobalConfig> { /** * The configuration object. * * @protected */ protected static configuration: Configuration & Record = {}; /** * Keys marked for not be deeply cloned when setting and returning values. */ public static usedAsReference: (PropertyKey | keyof Configuration)[] = ['headers']; /** * The config constructor. * * @param {object} configuration */ public constructor(configuration?: T) { if (configuration) { merge(GlobalConfig.configuration, configuration); } } /** * Get a value from the config. * * @param {string} key * @param {any=} defaultVal */ public get(key: K, defaultVal?: T[K]): T[K]; public get(key: PropertyKey, defaultVal?: D): D; public get(key: PropertyKey, defaultVal?: D): D { if (!this.has(key)) { return defaultVal!; } const value = GlobalConfig.configuration[key as string]; if (GlobalConfig.usedAsReference.includes(key) || GlobalConfig.usedAsReference.includes('*')) { return value; } return typeof value === 'function' ? value : cloneDeep(value); } /** * Determine whether a key is set in the config or not. * * @param {string} key */ public has(key: K): this is GlobalConfig> { return key in GlobalConfig.configuration; } /** * Set a config value. * * @param {string} key * @param {any} value */ public set(key: K, value: T[K]): asserts this is GlobalConfig>; public set(key: K, value: V): asserts this is GlobalConfig>; public set(key: string, value: unknown): void { if (GlobalConfig.usedAsReference.includes(key) || GlobalConfig.usedAsReference.includes('*')) { GlobalConfig.configuration[key] = value; return; } GlobalConfig.configuration[key] = typeof value === 'function' ? value : cloneDeep(value); } /** * Remove a config value. * * @param {string} key */ public unset(key: K): asserts this is GlobalConfig> { delete GlobalConfig.configuration[key]; } /** * Empty the configuration. * * @return {this} */ // @ts-expect-error public reset(): asserts this is GlobalConfig> { GlobalConfig.configuration = {}; } }