@clevercloud/reglage
v0.0.5
Published
Schema-driven configuration library built on [Zod](https://zod.dev). Define your options once and get validated, type-safe config from any number of sources.
Maintainers
Keywords
Readme
@clevercloud/reglage
Schema-driven configuration library built on Zod. Define your options once and get validated, type-safe config from any number of sources.
Usage
import { z } from 'zod';
import { createConfigBuilder } from '@clevercloud/reglage';
const builder = createConfigBuilder({
API_URL: {
schema: z.url().default('https://api.example.com'),
documentation: 'The API base URL',
},
PORT: {
schema: z.number().default(8080),
tags: ['server'],
documentation: 'Port to listen on',
},
SECRET: {
schema: z.string().min(1),
secret: true,
documentation: 'A required secret',
},
});
builder.addSource('defaults', { PORT: '3000' });
builder.addSource('env', process.env);
const config = builder.buildConfig(); // throws InvalidConfigError on validation failure
config.get('API_URL'); // string
config.get('PORT'); // number
config.getAll('server'); // { PORT: number }API
createConfigBuilder(schema)
Creates a ConfigBuilder from a schema record. Each key maps to an OptionDef:
| Field | Type | Description |
| --------------- | ---------------------------------- | -------------------------------------------------------- |
| schema | z.ZodType | Zod schema used to validate and transform the raw value. |
| secret | boolean (optional) | Marks the value as sensitive. |
| tags | string[] (optional) | Arbitrary tags for categorising options. |
| documentation | string \| Record<string, string> | Human-readable description of the option. |
ConfigBuilder
addSource(name, values)
Registers a named key/value source (e.g. "env", "file"). Sources are merged in order — later sources override earlier ones for the same key. Keys not present in the schema are silently ignored.
buildConfig()
Merges all sources and validates every value against the schema. Returns a Config instance or throws an InvalidConfigError.
refine(key, fn)
Adds a cross-field validation rule for the given key. The callback receives the original Zod schema and all resolved config values, and must return a Zod schema to validate the field against. Multiple refinements can be registered (even on the same key). They run after all fields have been individually validated.
// Make SECRET required when FEATURE_X is enabled
builder.refine('SECRET', (schema, resolved) => {
if (resolved.FEATURE_X) return z.string().min(1);
return schema;
});
// Restrict PORT in production
builder.refine('PORT', (schema, resolved) => {
if (resolved.MODE === 'production') {
return schema.refine((v) => v >= 1024, { message: 'Must be >= 1024 in production' });
}
return schema;
});Config
get(key)
Returns the resolved value for a single key.
getAll(tag?)
Returns all resolved values. When tag is provided, only options tagged with that value are included.
getSource(key)
Returns the name of the source that provided the winning value for a key (e.g. "env", "file"), or "default" if the value came from a Zod schema default.
getSourceHistory(key)
Returns the full override history for a single key, ordered from earliest (schema default) to latest (winning source). Each entry is a SourceHistoryEntry:
interface SourceHistoryEntry {
source: string;
rawValue: unknown;
resolvedValue?: unknown; // only set on the last (winning) entry
}builder.addSource('file', { PORT: 3000 });
builder.addSource('env', { PORT: '8080' });
const config = builder.buildConfig();
config.getSourceHistory('PORT');
// [
// { source: 'default', rawValue: 80 },
// { source: 'file', rawValue: 3000 },
// { source: 'env', rawValue: '8080', resolvedValue: 8080 }
// ]getAllSourceHistory()
Returns the full history for all keys as an object mapping each key to its SourceHistoryEntry[].
toString(format?)
Returns a human-readable string of all configuration values. Secret values are masked with ******. Keys are sorted alphabetically.
"simple"(default) — one line per key with the winning source:API_URL="https://api.example.com" (env) PORT=8080 (env) SECRET=****** (env)"chain"— one line per key with the full source chain:API_URL="https://api.example.com" (default -> env) PORT=8080 (default -> file -> env) SECRET=****** (env)"verbose"— multi-line output showing each source's raw value with an<-- activemarker on the winning entry:API_URL="https://api.example.com" (env) default -> "https://default.example.com" env -> "https://api.example.com" <-- active PORT=8080 (env) default -> 80 file -> 3000 env -> "8080" <-- active SECRET=****** (env) default -> ****** env -> ****** <-- active
InvalidConfigError
Thrown when validation fails. Exposes an issues array of ConfigIssue objects:
interface ConfigIssue {
key: string;
source: string | undefined;
message: string;
}