# @suaveplan/config - Layered configuration management: defaults, file, object, env, CLI layers merged in priority order with deep-merge, Zod validation, OTel instrumentation, and event-bus watch support. ## Summary Layered configuration management for Suaveplan. Resolves an ordered set of typed layers (defaults, file, object, env, CLI) in priority order, deep-merges the results, applies per-environment overrides, validates via a caller-supplied Zod schema or custom function, and exposes an immutable `ConfigStore` with live reload and event-bus change propagation. ## Documentation tree - [config-builder](./src/core/config-builder/config-builder.md) — _(no submodules)_ - [config-builder](./src/core/config-builder/config-builder.md) — _(no submodules)_ - [config-store](./src/core/config-store/config-store.md) — _(no submodules)_ - [config-store](./src/core/config-store/config-store.md) — _(no submodules)_ - [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_ - [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_ - [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_ - [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_ - [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_ - [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_ - [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_ - [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_ - [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_ - [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_ - [common](./src/types/common.md) — This module defines every public TypeScript interface and type alias used across the `@suaveplan/config` package. It is… - [schemas](./src/types/schemas.md) — This module exposes Zod schemas for every public options interface in `@suaveplan/config`. Using these schemas, callers… - [mask](./src/utils/mask.md) — This module provides low-level dot-notation path traversal utilities (`getByPath`, `setByPath`, `hasByPath`) and the `m… - [merge](./src/utils/merge.md) — This module provides two functions that form the merge backbone of the config pipeline: `deepMerge` performs a structur… - [config-builder](./src/core/config-builder/config-builder.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [common](./src/types/common.md) — This module defines every public TypeScript interface and type alias used across the `@suaveplan/config` package. It is… - [schemas](./src/types/schemas.md) — This module exposes Zod schemas for every public options interface in `@suaveplan/config`. Using these schemas, callers… - [mask](./src/utils/mask.md) — This module provides low-level dot-notation path traversal utilities (`getByPath`, `setByPath`, `hasByPath`) and the `m… - [merge](./src/utils/merge.md) — This module provides two functions that form the merge backbone of the config pipeline: `deepMerge` performs a structur… - [config-builder](./src/core/config-builder/config-builder.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [common](./src/types/common.md) — This module defines every public TypeScript interface and type alias used across the `@suaveplan/config` package. It is… - [schemas](./src/types/schemas.md) — This module exposes Zod schemas for every public options interface in `@suaveplan/config`. Using these schemas, callers… - [mask](./src/utils/mask.md) — This module provides low-level dot-notation path traversal utilities (`getByPath`, `setByPath`, `hasByPath`) and the `m… - [merge](./src/utils/merge.md) — This module provides two functions that form the merge backbone of the config pipeline: `deepMerge` performs a structur… - [config-builder](./src/core/config-builder/config-builder.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [common](./src/types/common.md) — This module defines every public TypeScript interface and type alias used across the `@suaveplan/config` package. It is… - [schemas](./src/types/schemas.md) — This module exposes Zod schemas for every public options interface in `@suaveplan/config`. Using these schemas, callers… - [mask](./src/utils/mask.md) — This module provides low-level dot-notation path traversal utilities (`getByPath`, `setByPath`, `hasByPath`) and the `m… - [merge](./src/utils/merge.md) — This module provides two functions that form the merge backbone of the config pipeline: `deepMerge` performs a structur… - [config-builder](./src/core/config-builder/config-builder.md) — _(no submodules)_- [config-store](./src/core/config-store/config-store.md) — _(no submodules)_ - [config-store](./src/core/config-store/config-store.md) — _(no submodules)_- [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_ - [cli-layer](./src/layers/cli-layer/cli-layer.md) — _(no submodules)_- [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_ - [defaults-layer](./src/layers/defaults-layer/defaults-layer.md) — _(no submodules)_- [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_ - [env-layer](./src/layers/env-layer/env-layer.md) — _(no submodules)_- [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_ - [file-layer](./src/layers/file-layer/file-layer.md) — _(no submodules)_- [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_ - [object-layer](./src/layers/object-layer/object-layer.md) — _(no submodules)_- [common](./src/types/common.md) — This module defines every public TypeScript interface and type alias used across the `@suaveplan/config` package. It is… - [schemas](./src/types/schemas.md) — This module exposes Zod schemas for every public options interface in `@suaveplan/config`. Using these schemas, callers… - [mask](./src/utils/mask.md) — This module provides low-level dot-notation path traversal utilities (`getByPath`, `setByPath`, `hasByPath`) and the `m… - [merge](./src/utils/merge.md) — This module provides two functions that form the merge backbone of the config pipeline: `deepMerge` performs a structur… ## Installation ```bash bun add @suaveplan/config ``` ## Quick Start ```ts import { createConfig, defaultsLayer, fileLayer, envLayer, cliLayer } from '@suaveplan/config'; import { readFileSync } from 'node:fs'; import z from 'zod'; const Schema = z.object({ server: z.object({ port: z.number(), host: z.string() }), db: z.object({ url: z.string(), pool: z.number(), password: z.string() }), log: z.object({ level: z.string() }), }); type AppConfig = z.infer; const store = createConfig({ layers: [ defaultsLayer({ server: { port: 3000, host: '0.0.0.0' }, db: { pool: 5, password: '' }, log: { level: 'info' } }), fileLayer({ content: JSON.parse(readFileSync('./config.json', 'utf-8')) }), envLayer({ prefix: 'APP_', mapping: { PORT: 'server.port', DB_URL: 'db.url', DB_PASS: 'db.password' } }), cliLayer({ args: process.argv.slice(2), mapping: { port: 'server.port' } }), ], validate: (raw) => Schema.parse(raw), sensitive: ['db.password', 'db.url'], environments: { production: { log: { level: 'warn' } }, development: { log: { level: 'debug' } } }, environment: process.env.NODE_ENV ?? 'development', }); console.log(store.get('server.port')); // number console.log(store.toMasked()); // db.password = '****' // Live reload await store.reload(); // Subscribe to changes const unsub = store.subscribe((next) => console.log('Config updated:', next)); ``` ## Module Documentation | Module | Description | |--------|-------------| | [`src/types/common.md`](src/types/common.md) | All public TypeScript interfaces and type aliases | | [`src/types/schemas.md`](src/types/schemas.md) | Zod option schemas for runtime validation | | [`src/core/config-builder/config-builder.md`](src/core/config-builder/config-builder.md) | `createConfig` orchestrator | | [`src/core/config-store/config-store.md`](src/core/config-store/config-store.md) | `createConfigStore` static store factory | | [`src/layers/defaults-layer/defaults-layer.md`](src/layers/defaults-layer/defaults-layer.md) | Static default values layer | | [`src/layers/object-layer/object-layer.md`](src/layers/object-layer/object-layer.md) | In-memory config object layer | | [`src/layers/env-layer/env-layer.md`](src/layers/env-layer/env-layer.md) | Environment variable layer + `coerceValue` | | [`src/layers/file-layer/file-layer.md`](src/layers/file-layer/file-layer.md) | Pre-parsed file content layer with watch mode | | [`src/layers/cli-layer/cli-layer.md`](src/layers/cli-layer/cli-layer.md) | CLI argument layer + `parseArgs` | | [`src/utils/merge.md`](src/utils/merge.md) | `deepMerge` and `mergeLayers` utilities | | [`src/utils/mask.md`](src/utils/mask.md) | Path utilities and `maskSensitive` | ## Layer Priorities | Layer | Priority | Description | |-------|----------|-------------| | `defaultsLayer` | 0 | Static baseline — always overridden | | `fileLayer` | 10 | Pre-parsed file content | | `objectLayer` | 20 | In-memory programmatic overrides | | `envLayer` | 30 | Environment variables | | `cliLayer` | 40 | CLI arguments — highest priority | ## API ### Core | Export | Description | |--------|-------------| | `createConfig(options)` | Resolves layers, merges, validates, returns live store | | `createConfigStore(options)` | Low-level static store factory | ### Layers | Export | Description | |--------|-------------| | `defaultsLayer(defaults)` | Static defaults at priority 0 | | `fileLayer(options)` | Pre-parsed file content at priority 10 | | `objectLayer(data, priority?)` | In-memory object at priority 20 | | `envLayer(options)` | Environment variables at priority 30 | | `cliLayer(options)` | CLI arguments at priority 40 | | `parseArgs(args, mapping)` | Parse raw argv into flag→value map | ### Utilities | Export | Description | |--------|-------------| | `deepMerge(base, override)` | Recursive object merge | | `mergeLayers(layers)` | Fold ordered layers with deepMerge | | `getByPath(obj, path)` | Read dot-notation path | | `setByPath(obj, path, value)` | Write dot-notation path | | `hasByPath(obj, path)` | Check dot-notation path existence | | `maskSensitive(data, paths, mask?)` | Replace sensitive paths | | `coerceValue(raw)` | Convert env-var string to typed value | ### Error Codes | Code | Description | |------|-------------| | `CONFIG.MISSING` | Required config key not found | | `CONFIG.INVALID_TYPE` | Value has wrong type | | `CONFIG.PARSE_FAILED` | Layer resolution threw | | `CONFIG.FILE_NOT_FOUND` | File layer file not found | | `CONFIG.ENV_NOT_SET` | Required env var not set | | `CONFIG.RELOAD_FAILED` | Reload aborted or layer threw | | `CONFIG.VALIDATION_FAILED` | Validator threw | ## Dependencies | Package | Role | |---------|------| | `@suaveplan/error` | `SuaveplanError` base, `defineCodes` | | `@suaveplan/types` | `LoggerLike`, `EventBusLike` | | `@suaveplan/events` | `EventBus` for file-layer watch mode | | `@suaveplan/env` | Coercion functions for env-var values | | `zod` | Option schemas | | `@opentelemetry/api` | Spans, counters, histograms | | `tslib` | TypeScript runtime helpers | ## Benchmarks Run with `bun run bench`. | Benchmark | Operations / sec (approx.) | |-----------|---------------------------| | `createConfig` 5 layers (cold) | TBD | | `store.get` 100x deeply nested key | TBD | | `mergeLayers` 2 layers | TBD | | `mergeLayers` 5 layers | TBD | | `mergeLayers` 10 layers | TBD | | `mergeLayers` 20 layers | TBD | _Run `bun run bench` to populate these numbers on your hardware._