platform-configuration
Type-safe configuration management for NestJS applications. Provides compile-time safe config keys, a strategy-based resolution pattern (environment variables, .env files, or custom sources), a global NestJS module, and a central registry for config discovery and validation.
Note: This package was extracted from
platform-core. Re-exports are still available fromplatform-corefor backward compatibility.
Package: @breadstone/archipel-platform-configuration
npm install @breadstone/archipel-platform-configurationQuick Start
import { Module } from '@nestjs/common';
import { ConfigModule, EnvironmentConfigStrategy } from '@breadstone/archipel-platform-configuration';
@Module({
imports: [
ConfigModule.forRoot({
strategyFactory: () => new EnvironmentConfigStrategy(),
}),
],
})
export class AppModule {}Config Keys
Type-safe config keys encode both the key name and the expected value type at compile time. This eliminates scattered process.env access and provides IDE autocomplete, "find usages", and refactoring support.
Defining Config Keys
import { createConfigKey } from '@breadstone/archipel-platform-configuration';
export const DATABASE_URL = createConfigKey<string>('DATABASE_URL');
export const CACHE_TTL = createConfigKey<number>('CACHE_TTL');
export const FEATURE_ENABLED = createConfigKey<boolean>('FEATURE_ENABLED');IConfigKey Interface
interface IConfigKey<TType = unknown> {
readonly _type?: TType; // Phantom type — compile-time only
readonly key: string; // The unique string identifier
}ConfigModule
forRoot — Application Root
Call once in the root module to bootstrap the global ConfigService.
ConfigModule.forRoot({
strategyFactory: () => new EnvironmentConfigStrategy(),
statics: { APP_VERSION: '1.0.0' }, // optional static overrides
});register — Library Modules
Call in each library module to declare configuration dependencies.
import { createConfigKey, type IConfigRegistryEntry } from '@breadstone/archipel-platform-configuration';
const SMTP_HOST = createConfigKey<string>('SMTP_HOST');
const SMTP_PORT = createConfigKey<number>('SMTP_PORT');
export const MAIL_CONFIG_ENTRIES: ReadonlyArray<IConfigRegistryEntry> = [
{ key: SMTP_HOST, module: 'mailing', required: true, description: 'SMTP server hostname' },
{ key: SMTP_PORT, module: 'mailing', required: false, defaultValue: 587, description: 'SMTP port' },
];
@Module({
imports: [ConfigModule.register('mailing', MAIL_CONFIG_ENTRIES)],
})
export class MailModule {}IConfigModuleOptions
| Property | Type | Description |
|---|---|---|
strategyFactory | () => ConfigStrategyBase | Factory that creates the resolution strategy for config values |
statics | Record<string, string> | Optional key-value overrides injected at startup |
ConfigService
Injected globally after ConfigModule.forRoot(). Automatically parses raw string values into numbers, booleans, and null.
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@breadstone/archipel-platform-configuration';
@Injectable()
export class SmtpClient {
private readonly _host: string;
private readonly _port: number;
constructor(configService: ConfigService) {
this._host = configService.get<string>('SMTP_HOST');
this._port = configService.tryGet<number>('SMTP_PORT', 587);
}
}| Method | Description |
|---|---|
get<T>(key) | Returns the parsed value. Throws ConfigKeyNotFoundError if missing. |
tryGet<T>(key, fallback) | Returns the parsed value, or fallback if the key is not set. |
has(key) | Returns true if the key exists in the strategy. |
ConfigRegistry
Static, global registry that collects all configuration keys registered by platform libraries. Enables a central overview of every environment variable the application depends on, grouped by source module.
import { ConfigRegistry } from '@breadstone/archipel-platform-configuration';
// All registered entries
const all = ConfigRegistry.getAll();
// Grouped by module
const grouped = ConfigRegistry.getByModule();
// Map { 'mailing' => [...], 'authentication' => [...] }Strategies
EnvironmentConfigStrategy
Resolves values from process.env.
import { EnvironmentConfigStrategy } from '@breadstone/archipel-platform-configuration';
ConfigModule.forRoot({
strategyFactory: () => new EnvironmentConfigStrategy(),
});FileConfigStrategy
Resolves values from a .env file on disk using dotenv.
import { FileConfigStrategy } from '@breadstone/archipel-platform-configuration';
ConfigModule.forRoot({
strategyFactory: () => new FileConfigStrategy('.env'),
});Custom Strategies
Extend ConfigStrategyBase to implement custom resolution (e.g. Azure App Configuration, AWS Parameter Store).
import { ConfigStrategyBase } from '@breadstone/archipel-platform-configuration';
export class AzureAppConfigStrategy extends ConfigStrategyBase {
public initialize(): void {
// Connect to Azure App Configuration
}
public resolve<T>(key: string): T {
// Fetch from Azure
}
public tryResolve<T>(key: string, fallback: T): T {
// Attempt fetch, return fallback on miss
}
public has(key: string): boolean {
// Check existence
}
}Error Handling
| Error | Description |
|---|---|
ConfigKeyNotFoundError | Thrown when get() is called for a key that does not exist in the active strategy. |
Module Summary
| Export | Type | Description |
|---|---|---|
ConfigModule | NestJS Module | Global configuration bootstrap and registration |
ConfigService | Service | Type-safe config value access |
ConfigRegistry | Static class | Central registry of all registered config entries |
ConfigStrategyBase | Abstract class | Base class for configuration resolution strategies |
EnvironmentConfigStrategy | Strategy | Resolves from process.env |
FileConfigStrategy | Strategy | Resolves from .env files via dotenv |
createConfigKey<T>() | Factory | Creates a typed config key |
IConfigKey<T> | Interface | Typed config key contract |
IConfigRegistryEntry<T> | Interface | Registry entry with module, required, default |
IConfigModuleOptions | Interface | Options for ConfigModule.forRoot() |
ConfigKeyNotFoundError | Error | Thrown on missing required config keys |