Config
@strata-js/util-config is a configuration loading utility that supports YAML and JSON files with environment variable substitution and file includes. It stores named config objects and retrieves them with full TypeScript generics support.
Installation
npm install @strata-js/util-configUsage
import configUtil from '@strata-js/util-config';
interface AppConfig
{
server : {
host : string;
port : number;
};
database : {
connectionString : string;
};
}
// Load a config file (typically at startup)
configUtil.load('./config.yml');
// Retrieve the parsed config anywhere in your application
const config = configUtil.get<AppConfig>();
console.log(config.server.port); // 8080The default export is a singleton instance of ConfigUtil. You can also import the class directly if you need multiple independent instances:
import { ConfigUtil } from '@strata-js/util-config';
const myConfig = new ConfigUtil();
myConfig.load('./my-config.yml');API
load(filePath, name?, options?)
configUtil.load(filePath : string, name ?: string, options ?: ConfigLoaderOptions) : voidReads and parses a configuration file, storing the result under name.
| Parameter | Type | Default | Description |
|---|---|---|---|
filePath | string | — | Path to the config file. If not provided, uses the CONFIG_FILE environment variable. |
name | string | 'default' | Name to store the config under. Allows loading multiple config files. |
options | ConfigLoaderOptions | See below | Options controlling parsing behavior. |
Supported file formats are determined by extension:
| Extension | Format |
|---|---|
.yml, .yaml | YAML |
.json | JSON |
ConfigLoaderOptions
| Option | Type | Default | Description |
|---|---|---|---|
substituteEnvironmentVariables | boolean | true | Replace environment variable references in the file content before parsing. |
mergeIncludes | boolean | true | Process include directives and merge included files into the config. |
get<T>(name?)
configUtil.get<T>(name ?: string) : TReturns the config stored under name. Throws an error if no config has been loaded under that name.
| Parameter | Type | Default | Description |
|---|---|---|---|
name | string | 'default' | The name the config was stored under during load() or set(). |
set<T>(config, name?)
configUtil.set<T extends Record<string, unknown>>(config : T, name ?: string) : voidStores a config object directly, bypassing file loading. Useful for testing or when config comes from an external source.
| Parameter | Type | Default | Description |
|---|---|---|---|
config | T | — | The config object to store. |
name | string | 'default' | The name to store the config under. |
delete(name?)
configUtil.delete(name ?: string) : voidRemoves the config stored under name.
| Parameter | Type | Default | Description |
|---|---|---|---|
name | string | 'default' | The name of the config to remove. |
clear()
configUtil.clear() : voidRemoves all stored configs.
Environment Variable Substitution
When substituteEnvironmentVariables is enabled (the default), the file content is scanned for environment variable references before parsing. Three syntaxes are supported:
| Syntax | Example |
|---|---|
$VAR | $HOSTNAME |
${VAR} | ${REDIS_HOST} |
| |
If a referenced variable is not set, the reference is left as-is in the string.
# config.yml
server:
host: "$HOSTNAME"
port: 8080
database:
connectionString: "postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/mydb"File Includes
Config files can include other files using the include key. Included files are loaded first, then the base file's values are merged on top (base values win).
Single include:
# config/local.yml
include: "base.yml"
service:
serviceGroup: "MyService"
logging:
level: debug
prettyPrint: trueMultiple includes:
include:
- "base.yml"
- "logging-defaults.yml"
service:
serviceGroup: "MyService"Include paths are resolved relative to the file that contains the include directive. Includes can be nested up to 10 levels deep by default. Set the INCLUDE_DEPTH environment variable to change this limit.
Examples
Named Configs
Load separate configs for different parts of your application:
import configUtil from '@strata-js/util-config';
configUtil.load('./config/service.yml', 'service');
configUtil.load('./config/database.yml', 'database');
const serviceConfig = configUtil.get<ServiceConfig>('service');
const dbConfig = configUtil.get<DatabaseConfig>('database');Environment-based Config Files
A common pattern is to load different files based on the current environment:
import configUtil from '@strata-js/util-config';
const env = process.env.ENVIRONMENT ?? 'local';
configUtil.load(`./config/${ env }.yml`);
const config = configUtil.get<AppConfig>();Testing
Use set() to inject config directly in tests without touching the filesystem:
import configUtil from '@strata-js/util-config';
beforeEach(() =>
{
configUtil.set({
server: { host: 'localhost', port: 0 },
database: { connectionString: 'sqlite::memory:' },
});
});
afterEach(() =>
{
configUtil.clear();
});Base Config with Overrides
Use file includes to share common configuration across environments:
# config/base.yml
backend:
type: "redis-streams"
redis:
host: "localhost"
port: 6379
discovery:
enabled: true# config/production.yml
include: "base.yml"
backend:
redis:
host: "$REDIS_HOST"
password: "$REDIS_PASSWORD"
logging:
level: info
prettyPrint: false