Runtime Configurator
Painless runtime configuration for Node.js applications.
Features:
- fills in configuration values with
.js
and.json
files, environment variables and command line arguments, - validates configuration values with declared validators,
- supports any kind of data types: booleans, numbers, strings, objects and arrays,
- freezes resolved configuration values for mistake proofing (according to poka-yoke principle),
- does not collide with most popular CLI tools like Commander.js, oclif or Yargs,
- prints configuration as table into standard output (useful to generate help commands),
- production ready!
Table of contents
Installation
$ npm install --save runtime-configurator
Usage
1. Import what you need
import {
ConfigurationBagInterface,
ConfigurationBag,
ConfigurationItemInterface,
ConfigurationItem,
ConfigurationValidatorInterface,
ArrayValidator,
BooleanValidator,
EnumerableValidator,
NumberValidator,
ObjectValidator,
RegularExpressionValidator,
StringValidator,
ConfigurationSourceInterface,
CommandLineArgumentsSource,
DirectorySource,
EnvironmentVariablesSource,
FileSource,
ConfigurationPrinterInterface,
StandardOutputPrinter
} from "runtime-configurator";
2. Declare configuration items
const items: ConfigurationItemInterface[] = [
new ConfigurationItem(
"httpServer.port",
"Port to be exposed by HTTP server.",
8080,
[
new NumberValidator(true, 1024, 49151)
]
)
];
Note: use camel case names and dots as separator. This library requires that convention to properly resolve env vars and cli args.
3. Declare configuration sources
const sources: ConfigurationSourceInterface[] = [
new DirectorySource("/etc/app", false),
new FileSource("/etc/app.json", false),
new DirectorySource(path.join(os.homedir(), ".app"), false),
new FileSource(path.join(os.homedir(), ".app.json"), false),
new EnvironmentVariablesSource(process.env, "APP"),
new CommandLineArgumentsSource(process.argv, "override")
];
Note: the order matters here. Every source might override values resolved by previous sources. It is recommended to place env vars and cli args at the bottom of the list.
4. Create a configuration bag
const configuration: ConfigurationBagInterface =
new ConfigurationBag(items, sources);
5. Get value from the configuration bag
const port: number =
configuration.get("httpServer.port") as number;
Btw. now you are able to override httpServer.port
value with:
- any
.js
and.json
file inside/etc/app
directory, -
/etc/app.json
file, - any
.js
and.json
file inside/home/<username>/.app
directory, -
/home/<username>/.app.json
file, - following environment variables:
-
APP__HTTP_SERVER__PORT=1234
, -
APP__HTTP_SERVER='{"port":1234}'
, -
APP='{"httpServer":{"port":1234}}'
,
-
- following command line arguments:
-
--override=http-server.port=1234
, -
--override=http-server='{"port":1234}'
, -
--override='{"httpServer":{"port":1234}}'
.
-
Enjoy!
Validators
Every configuration item can be validated
with one or more validators. Example below
shows how to ensure that mailer.enabled
will always be a boolean.
const item: ConfigurationItemInterface = new ConfigurationItem(
"mailer.enabled",
"Enables or disables emails sending.",
true,
[
new BooleanValidator()
]
);
Boolean validator
new BooleanValidator()
Just checks if value is a boolean.
Number validator
new NumberValidator(true, 1, 10)
Checks if value is an integer, bigger than or equal 1 and smaller than or equal 10.
String validator
new StringValidator(5, 10)
Checks if value is a string with minimum length of 5 and maximum length of 10.
Regular expression validator
new RegularExpressionValidator(/.*/)
Checks if value is a string and passes regular expression test.
Enumerable validator
new EnumerableValidator([null, true, 1, "foo"])
Checks if value equals null
, true
, 1
or "foo"
.
Object validator
new ObjectValidator({ foo: new BooleanValidator() })
Checks if value is an object and it's foo
property
is a boolean.
Array validator
new ArrayValidator(new BooleanValidator(), 1, 3)
Checks if value is an array of booleans with minimum length of 1 and maximum length of 3.
Ad-hoc validator
{
validate(value: any): string[] {
if (value === "0.0.0.0") {
return ['Value can not equal "0.0.0.0".'];
}
return [];
},
}
This specific validator checks if value does not
equal "0.0.0.0"
.
Examples
There are two runnable examples. One with pure JavaScript and the second one with TypeScript.
FAQ
What is a runtime configuration?
Runtime configuration is a set of values which vary between application deployments, aka. values which we do not know during application development.
See more at The Twelve-Factor App.
Development
$ git clone git@github.com:damlys/nodejs-runtime-configurator.git
$ cd nodejs-runtime-configurator/
$ npm audit
$ npm install
$ npm run build
$ npm run lint(-fix)
$ npm run test(-coverage|-watch)