import process from "process"; import convict, { SchemaObj } from "convict"; import { IServerConfig, ServerConfig } from "./server"; import { IMetricsConfig, MetricsConfig } from "./metrics-server"; import { IAppMetaConfig, AppMetaConfig } from "./app-meta"; import { ICorsConfig, CorsConfig } from "./cors"; import { ILoggingConfig, LoggingConfig } from "./logging"; import { ExtendedConvict } from "./types"; import { MetamigoConvictFormats } from "./formats"; type IEnvConfig = "production" | "development" | "test"; const EnvConfig: SchemaObj = { doc: "The application environment", format: ["production", "development", "test"], default: "development", env: "NODE_ENV", }; export const configBaseSchema = { env: EnvConfig, server: ServerConfig, meta: AppMetaConfig, cors: CorsConfig, metrics: MetricsConfig, logging: LoggingConfig, }; /** * * The metamigo base configuration object. Use this for easy typed access to your * config. * */ interface IMetamigoConfig { env: IEnvConfig; server: IServerConfig; meta: IAppMetaConfig; cors: ICorsConfig; metrics: IMetricsConfig; logging: ILoggingConfig; isProd?: boolean; isTest?: boolean; isDev?: boolean; frontend: any; nextAuth: any; } export type IMetamigoConvict = ExtendedConvict; export type { IServerConfig, IMetricsConfig, IAppMetaConfig, ICorsConfig, ILoggingConfig, IMetamigoConfig, }; export * from "./formats"; export * from "./generate"; export * from "./print"; export * from "./types"; /** * Loads your applications configuration from environment variables and configuration files (see METAMIGO_CONFIG). * * @param schema your schema definition * @param override an optional object with config value that will override defaults but not config files and env vars (see [convict precedence docs](https://github.com/mozilla/node-convict/tree/master/packages/convict#precedence-order )) * @returns the raw convict config object */ export const loadConfigurationRaw = async ( schema: convict.Schema, override?: Partial ): Promise> => { convict.addFormats(MetamigoConvictFormats); const config: ExtendedConvict = convict(schema); const env = config.get("env"); config.isProd = env === "production"; config.isTest = env === "test"; config.isDev = env === "development"; try { if (process.env.METAMIGO_CONFIG) { config.loadFile(process.env.METAMIGO_CONFIG); } } catch (error) { const msg = ` 🚫 Your application's configuration is invalid JSON. 🚫 ${error} `; throw new Error(msg); } if (override) { config.load(override); } try { config.validate({ allowed: "strict" }); } catch (error: any) { const msg = ` 🚫 Your application's configuration is invalid. 🚫 ${error.message} `; throw new Error(msg); } // set our helpers // eslint-disable-next-line @typescript-eslint/no-explicit-any const configDirty = config as any; configDirty.set("isProd", config.isProd); configDirty.set("isTest", config.isTest); configDirty.set("isDev", config.isDev); return config; }; /** * Loads your applications configuration from environment variables and configuration files (see METAMIGO_CONFIG). * * @param schema your schema definition * @param override an optional object with config value that will override defaults but not config files and env vars (see [convict precedence docs](https://github.com/mozilla/node-convict/tree/master/packages/convict#precedence-order )) * @returns a vanilla javascript object with the config loaded values */ export const loadConfiguration = async ( schema: convict.Schema, override?: Partial ): Promise => { const c = await loadConfigurationRaw(schema, override); return c.getProperties(); };