@caeljs/config v0.9.21
ConfigJS - Type-Safe Environment Configuration Manager
Overview
ConfigJS is a robust, type-safe configuration management system for Node.js applications. It provides a structured way to define, validate, and access environment variables and other configuration sources with full TypeScript support.
Features
- Type-safe configuration with TypeScript inference
- Multiple drivers (env, file, etc.)
- Synchronous and asynchronous support
- Validation and transformation of configuration values
- Nested configuration structures
- Caching of resolved values
- CRUD operations for configuration values
- Schema definition for all configuration keys
Installation
npm install @caeljs/config
# or
yarn add @caeljs/config
# or
bun add @caeljs/configBasic Usage
1. Define your configuration schema
import { c, ConfigJS, ConfigJSDriver } from "@caeljs/config";
const Config = new ConfigJS(envDriver, {
db: {
host: c.string().prop("DB_HOST"),
port: c.number().prop("DB_PORT"),
username: c.string().prop("DB_USER"),
password: c.string().secret().prop("DB_PASS"),
},
environment: c.enum(["development", "production", "staging"]).prop("NODE_ENV"),
featureFlags: {
newUI: c.boolean().default(false).prop("NEW_UI_ENABLED"),
}
});2. Load configuration
// Load
Config.load();
// Or load with additional options
Config.load({
processEnv: false,
});3. Use configuration values
// Get values
const dbHost = Config.get("db.host");
const isProduction = Config.get("environment") === "production";
// Set values
Config.set("featureFlags.newUI", true);
// Delete values
Config.del("db.password");API Reference
Main configuration manager class.
Constructor:
import { ConfigJS } from "@caeljs/config";
new ConfigJS(driver: AnyConfigDriver, shapes: Shapes)Properties:
async: Boolean indicating if driver operates asynchronouslycached: Object with cached values of all configurationsshapes: Original shape definitionsdriver: The configuration driver instanceconfig: Driver-specific configuration
Methods:
getSchema(key): Get the shape definition for a keyget(key): Get a configuration valueset(key, value): Set a configuration valuedel(key): Delete a configuration valueconf(key): Get configuration metadatakeys(): Get all configuration keyshas(...keys): Check if keys existload(opts): Load configurationsave(): Save current configuration
Shape Types
All shape types extend BaseShape and provide validation and transformation:
StringShape: String valuesNumberShape: Numeric valuesBooleanShape: Boolean valuesEnumShape: Enumeration of allowed valuesObjectShape: Nested objectsArrayShape: Arrays of valuesRecordShape: Dictionary types
Each shape provides methods:
.prop(envVar): Map to environment variable.default(value): Set default value.secret(): Mark as sensitive value.refire(fn): Add custom validation.transform(fn): Add transformation.coerce(): Enable type coercion- And another props, based on type
Drivers
Built-in drivers:
envDriver: Environment variables driver
Driver interface:
interface AnyConfigDriver<IsAsync extends boolean, ConfigType> {
async: IsAsync;
config: ConfigType;
get(shape: BaseShape<any>): IsAsync extends true ? Promise<any> : any;
set(shape: BaseShape<any>, value: any): IsAsync extends true ? Promise<void> : void;
del(shape: BaseShape<any>): IsAsync extends true ? Promise<void> : void;
has(...shapes: BaseShape<any>[]): IsAsync extends true ? Promise<boolean> : boolean;
load(shapes: BaseShape<any>[]): IsAsync extends true ? Promise<void> : void;
save(shapes: BaseShape<any>[]): IsAsync extends true ? Promise<void> : void;
}Advanced Usage
Custom Validation
const config = new ConfigJS(envDriver, {
port: c.number()
.prop("APP_PORT")
.refine(val => (val > 1024), "Port must be > 1024")
.default(3000),
});Creating Custom Drivers
import { c, ConfigJS, ConfigJSDriver } from "@caeljs/config";
const fileDriver = new ConfigJSDriver({
async: true,
config: { filePath: './config.json' },
async get(shape) {
const config = await readJsonFile(this.config.filePath);
return config[shape._prop];
},
// Implement other required methods...
});
const fileConfig = new ConfigJS(fileDriver, {
settings: c.object({
logLevel: c.string().prop("logLevel"),
}),
});Best Practices
- Centralize configuration: Define all configuration in one place
- Use descriptive names: For both config keys and env vars
- Validate early: Validate configuration at application startup
- Use secrets marking: For sensitive values
- Provide defaults: Wherever possible
- Document schema: Add comments explaining each configuration
Type Safety
ConfigJS provides complete TypeScript support:
import { c, ConfigJS } from "@caeljs/config";
const config = new ConfigJS(envDriver, {
server: {
port: c.number().prop("PORT"),
ssl: c.boolean().prop("SSL_ENABLED"),
},
});
// Type is inferred as number
const port = config.get("server.port");
// Type error - port is a number
config.set("server.port", "8080"); // Error: Type 'string' is not assignable to type 'number'License
MIT
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago