chimera-config
v0.6.0
Published
The easiest, declarative, type-safe, and _traceable_ way to write configurations.
Readme
chimera-config
The easiest, declarative, type-safe, and traceable way to write configurations.
⚠️⚠️ This package is under active development ⚠️⚠️
Features
♻️ Polymorph
Use env files, command line arguments, config files (like JSON or YAML) or write your own.
👮 Type safe
No more any for your configs. All your configs are properly inferred and
validated.
📜 Declarative
Easy to read, easy to write, easy to understand. No surprises where values come from or where they were modified.
🛤️ Trackable
When enabled, track where your configurations come from and store meta data for them.
✍ Generate config templates
By tracing where your configs come from and adding meta-data, generate example
.env files, default configs, or Markdown tables for documentation. All within
your code.
🍃 No dependencies
Pure JS for a small footprint and overhead.
Non-Features
- 🙅 Handle complex structures, like
docker-compose.yml. - 🙅 Input validation, beyond basic type-checks. However, you can bring your own, like zod (WIP).
- 🙅 Being a sophisticated CLI args parser. This library is meant to set
configs/flags via CLI args. But nothing fancy like the
dockerorawsCLI.
Roadmap
- More supported configs
- JSON (WIP)
- YML
- TOML
- More supported generators
- JSON schema
- YML
- TOML
- Support for validators/transformers
- Standard Schema implementations, like zod (WIP)
- Async configs (like using fetch)
- Consider migrating from TS to pure JS with JSDoc type annotations.
Code Example
import * as c from '@any/config';
// Define where to get values from
c.useStores([new c.EnvStore()]);
// Print all paths relative to dirname
c.setRootDir(import.meta.dirname);
// Getting the caller location is a bit expensive, so we have to enable it if we
// want it
c.enableCallerLocation();
// 1️⃣ Define your config
const dbConfig = c.config(
'db', // Prefix of this config
// Define your config as object
{
host: c.string().with(c.fallback(() => 'localhost')),
port: c.port().with(c.fallback(() => 5432)),
auth: {
username: c.string().with(c.fallback(() => 'admin')),
password: c.string().with(c.fallback(() => 'admin')),
},
transaction: {
timeout: c
.integer()
.with(
c.betweenIncl(1_000, 60_000),
c.description(
'After which time (in milliseconds) transactions are aborted'
)
),
},
}
);
// 2️⃣ Access props of your config with type-safety
const userName: string = dbConfig.auth.username;
console.log(userName);
// 3️⃣ Generate a .env template
console.log(c.generateDotEnvTemplate());This will produce a template for your .env file similar to this:
# This file was generated by running script from-readme.ts:1:530
# db.host at from-readme.ts:1:140
#
# Default: ()=>"localhost"
#DB_HOST=
# db.port at from-readme.ts:1:140
#
# Value must:
# - be an integer
# - be between 0 and 65535 (both inclusive)
# - be a valid IP port
#
# Default: ()=>5432
#DB_PORT=
# db.auth.username at from-readme.ts:1:140
#
# Default: ()=>"admin"
#DB_AUTH_USERNAME=
# db.auth.password at from-readme.ts:1:140
#
# Default: ()=>"admin"
#DB_AUTH_PASSWORD=
# db.transaction.timeout at from-readme.ts:1:140
# After which time (in milliseconds) transactions are aborted
#
# Value must:
# - be an integer
# - be between 1000 and 60000 (both inclusive)
DB_TRANSACTION_TIMEOUT=