A simple configuration system allowing multiple configuration layers (e.g. defaults, user-defined config)
Each layer is treated independently. If the configuration is queried, all layers are scanned from the layer with the highest priority to the one with the lowest. The first layer that can resolve the queried path will be the one returning the configured value.
By default, an instance of
LayeredConfiguration is created when the module is required.
// Load a ready-to-use LayeredConfiguration instancelet config = ;// If you want to create your own instance, use this instead:let LayeredConfig = LayeredConfiguration;let myConfig = ;
Before any configuration values can be read or written, we need to add one or more layers to the configuration.
If added by using
addlayer(), every new layer will have a higher priority than the ones that were added before.
// Add a first layer including some dataconfig;// Add another layer// This one has a higher priority than "layerOne"config;consoledirconfig; // ["layerTwo", "layerOne"]
getLayerNames() returns the names of the layers inside the configuration ordered from highest to lowest priority.
Each value inside the configuration hierarchy can be addressed by using a configuration path that describes the position you want to access. By default, configuration paths use "." as separator. To get the value of "bar" in our example above, the corresponding configuration path would be
Querying the configuration is done by using
let valueOfBar = config;console; // Output: 'baz'// This will output "overwritten", since layerTwo has the highest priorityconsole;
If you want to query data from a specific layer, just add the layer name as second parameter:
console; // Output: 'bar'
You can even change the priority by passing the layer names in the order they should be queried:
console; // Output: 'bar'
Data is written to the config using the
set() method. It takes up to three parameters: The path to write to, the value to write and the layer the value shall be stored in. If the layer name is omitted, the new value will be written into the layer with the highest priority:
config; // Writes to "layerTwo"config; // Writes to "layerOne"
You can write complete object hierarchies, too:
Loading configuration data
From the filesystem
layered-config reads and writes its configuration data using Hjson. This way, the configuration files can be written in a little bit more relaxed way and contain - for example - comments.
For more information about Hjson, see the Hjson website.
You can choose to either load each layer one by one using
loadFromFile() or to fill the whole configuration by reading all
.hjson files from a directory using
loadFromDirectory(). Both function return Promises that resolve when the load operations have completed.
// Load the contents of userData.hjson into a new layer named "userData"config;// Load the same file into a layer named "foo"config;// Cleanupconfig;// Load all (h)json files from ./data into the configuration// Files will be loaded in alphabetical orderconfig;// Assuming that the directory contains the files "foo.hjson", "bar.json" and "baz.hjson",let names = config; // ["foo", "baz", "bar"]
If both, a
.hjson and a
.json file exist having the same filename, the resulting configuration will only contain the data from the
.json file, because it will be loaded after the
.hjson one, thus overwriting its data.
From environment variables
You can also load configuration data from environment variables using
loadFromEnv(). This function takes an option object which configures the way, the environment variables are processed.
The available options are:
lowerCase(Boolean): convert environment variable names to lowercase? (default:
separator(String): if set, the variable name will be split into a path using the separator (default:
whitelist(String): if set, only the variables inside this array will be loaded into the layer (default
match(regex): if set, only variables that match the regular expression will be loaded into the layer (default:
match are set, all environment variables will be imported into the configuration layer.
// Add a layer containing process.env variables// If no layer name is given, a new layer named 'process_env' will be createdconfig;console
Saving configuration data into files
When saving the configuration data you can either write the data of one layer into a single file using
saveToFile() or write the data of all layers into Hjson files inside a directory, each having the layers' name by using
Just like the load methods, each save method returns a Promise.
saveToDirectory(), only those layers will be written to disk that have their
writeToDisk property set to
// Add some layers with dataconfigwriteToDisk = true;config;configwriteToDisk = true;// Write layer "two" to diskconfig;// This will write layers "one" and "three" to the target directoryconfig;// The "data" directory now contains the files "one.hjson" and "three.hjson"