@setu-ts/config-plugin — validated environment configuration
Add it: setu add config adds the dependency; register ConfigPlugin() in setu.config.ts
(the REST scaffold already does). It provides CAPABILITIES.CONFIG (IConfig).
Read a setting in a route
import { CAPABILITIES } from "@setu-ts/common";
import type { IConfig, IRouterApi } from "@setu-ts/common";
export function registerSettingsRoutes(router: IRouterApi): void {
router.get("/currency", {
handler: (ctx) => {
const config = ctx.services.get<IConfig>(CAPABILITIES.CONFIG);
return ctx.response.json({ currency: config.get("CURRENCY", { default: "INR" }) });
},
});
}
Load once before constructing plugins
Pass the runtime used by your composition root, then register the returned plugin:
import type { IPlugin, IRuntimeServices } from "@setu-ts/common";
import { ConfigPlugin, loadConfig } from "@setu-ts/config-plugin";
export async function preloadConfig(runtime: IRuntimeServices): Promise<IPlugin> {
const config = await loadConfig(runtime, { envFilePath: ".env", envFileOptional: true });
return ConfigPlugin({ instance: config });
}
Behaviour the types do not show
- Runtime environment values override dotenv files; in
envFilePatharrays the first file wins. - Loading merges, expands references, then validates.
expandVariablesdefaults totrue;validationSchemaoutput becomes the snapshot, including coercions and defaults. - Without schema coercion, environment values remain strings:
config.get<T>does not convert them. getreturnsundefinedwhen absent, or the supplied default;getOrThrowthrows andhasreturns false forundefinedvalues.envFileOptionaltolerates an absent path; a present file that cannot be read still throws. Any configured file path requires a runtime filesystem.instanceuses that snapshot directly, ignoring loading, expansion andvalidationSchema; declaredsectionsstill validate.
Other options
defineConfigSectiondeclares prefixedkeysand a schema; pass it insectionsand read withgetConfigSectionusing the same definition.diagnosticswithenabled: trueand key/file aliases enables value-free provenance underCAPABILITIES.CONFIG_DIAGNOSTICS(IConfigDiagnosticsSource); omitted, the source is disabled.