One man's constant is another man's variable.
(Alan Perlis)
@arpinum/config is a simple module to read configuration from env variables.
It helps you implement a 12-factor configuration.
npm install @arpinum/config --save
Given those env variables:
export DATABASE_URL=mongodb://localhost:27017/database
export LOG_LEVEL=info
In your app, require the module then read the configuration:
const { loadConfiguration } = require("@arpinum/config");
const configuration = loadConfiguration({
databaseUrl: {
env: "DATABASE_URL",
},
logLevel: {
env: "LOG_LEVEL",
},
});
console.log(configuration);
The output is:
{
databaseUrl: 'mongodb://localhost:27017/database',
logLevel: 'info'
}
Configuration can be nested:
const configuration = loadConfiguration({
database: {
url: {
env: "DATABASE_URL",
},
user: {
env: "DATABASE_USER",
},
},
});
console.log(configuration);
The output is:
{
database: {
url: the_url,
user: the_user
}
}
A default value can be used if the variable is missing:
const configuration = loadConfiguration({
logLevel: {
env: "LOG_LEVEL",
default: "info",
},
});
This is particularly useful for development environment.
Though default values can be described in schema, it may be useful to override them if you load configuration from another source.
const configuration = loadConfiguration(
{
log: {
level: {
env: "LOG_LEVEL",
},
},
},
{
defaults: {
log: { level: "debug" },
},
},
);
More than one variable can be provided for a key. The first defined value will be used.
Example:
const configuration = loadConfiguration({
port: {
env: ["PORT", "DB_PORT", "PG_PORT"],
},
});
This is usefull when variables change between deployment environments.
If a property is marked as required, the module will throw an error if the corresponding variable is missing.
Example:
const configuration = loadConfiguration({
logLevel: {
env: "LOG_LEVEL",
required: true,
},
});
A property can be cast to a given type, provided representation is compatible.
Example:
const configuration = loadConfiguration({
retryCount: {
env: "RETRY_COUNT",
type: "integer",
},
});
Available types:
- string (default),
- integer,
- boolean,
- float
Boolean representations (case insensitive):
- true: true, yes
- false: false, no
A property can be converted using a custom conversion function.
Example:
const configuration = loadConfiguration({
timeoutInMilliseconds: {
env: "TIMEOUT_IN_SECONDS",
convert: (v) => v * 1000,
},
});
My main source of inspiration is 12factor-config, a simple module made by chilts.
I thank him for his work, his module helped me a while.