smconfig
v2.1.2
Published
Application configuration module for Node.js
Downloads
8
Maintainers
Readme
SMConfig v2.1
Application configuration module for Node.js.
Features:
- Simple, yet flexible APIs
- Automatic environment detection based on hostname
- Override configuration at runtime with environmental variables or ".env" files
- Load configuration from JSON, YAML and Hjson documents
- Optional plugin for Hapi 17+
This module is written in TypeScript and transpiled to JavaScript. All typings are available alongside the code.
This code is licensed under the terms of the MIT license (see LICENSE.md).
Full documentation
Full documentation is available on GitHub pages.
Add to your project
Install from NPM:
npm install --save smconfig
API Guide
Include the module with:
const SMConfig = require('smconfig')
The module exports a class named SMConfig
.
Constructor: SMConfig(config, env, options)
const conf = new SMConfig(config, env, options)
Parameters
config
: configuration object (read below for description)env
: when set, forces a specific environmentoptions
: dictionary with options:options.envVarName
: name of the environmental variable where options are passed (default:SMCONFIG
)
The constructor determines the environment, then loads the configuration for the environment and stores it in the object.
Config data
The config
paramter can be:
- A plain JavaScript object, respecting the structure in the example below.
- The filename (as string) of a JSON, YAML or Hjson file. File type is determined by the extension, and supported ones are:
*.json
,*.yaml
,*.yml
and*.hjson
. The content of the file must represent a structure like the one below. - Another instance of SMConfig. In this case, the constructor will merge the content of
config.all
from the other object into the "default" section. - An array mixing any of the above. In this case, data will be merged from left to right: subsequent values overwrite property assignments of previous values.
Config object structure
The config object must have the following basic structure:
- The
default
key is always required, containing the default config values for all the environments. - The
hostnames
key can be defined. This is a dictionary in which the key is the environment name, and the value is an array of possible hostnames to match (exact string matches, strings with wildcard matching using*
, or regular expressions). - Any other key represents the configuration for the environment named like the key. For example, you can define the configuration for the "production" environment in the
production
key, and that will inherit from thedefault
configuration all values not specified.
For example:
const configData = {
// Default configuration, for all environments
default: {
key1: 'value1',
key2: 'value2'
},
// Each subsequent key is the name of the environment;
// this can be anything you want
dev: {
// Custom environments inherit all keys from the default
// environment, but can be overwritten here
key1: 'override',
newkey: 'helloworld'
},
production: {
key1: 'override'
},
otherenvironment: {},
// The hostnames object contains a dictionary of hostnames that are
// mapped to a specific environment.
hostnames: {
// Name of the environment, then list of hostnames
dev: [
'alessandro.localdomain'
],
production: [
// Can use * as wildcard
'*.example.com',
// Can also use RegExp objects
/(.*?)\.example\.com$/i
]
}
}
// Example:
const conf = new SMConfig(configData)
Load config data from files
In place of a config object, you can pass a string with the path of a file to load with the config object.
// Load a file
const obj = new SMConfig('config.json')
// Load multiple files
const obj = new SMConfig(['config.json', 'config2.yaml'])
For sample configuration files in JSON, YAML and Hjson, check the documents in the test folder:
When using YAML, you can also use the following types that are not supported by JSON and Hjson: (see documentation for js-yaml for more information)
- RegExp:
!!js/regexp /pattern/gim
- Functions:
!!js/function 'function () {...}'
- Undefined:
!!js/undefined ''
Using environmental variables
Configuration can also be passed at runtime (and it can override what is defined in the application or in the config files) with an environmental variable. The variable SMCONFIG
(name can be changed with options.envVarName
) can contain a set of key-values. You can also append _1
, _2
, etc, to pass multiple environmental variables. For example:
# SMConfig will store 'Passw0rd' for the 'databasePassword' key
SMCONFIG="databasePassword=Passw0rd" \
node myapp.js
# Nested properties can be passed too, for example `database.password`
SMCONFIG="database.password=Passw0rd" \
node myapp.js
# Multiple values can be passed
SMCONFIG="database.password=Passw0rd database.username=admin" \
node myapp.js
# You can add multiple environmental variable by appending `_#`
SMCONFIG="passphrase='hello world'" \
SMCONFIG_1="hello=world" \
SMCONFIG_2="a=b" \
node myapp.js
# If the value contains a space, quote it
SMCONFIG_1="passphrase='hello world'" \
SMCONFIG_2="secret=\"psshhh\"" \
node myapp.js
You can also use the SMCONFIG_FILE
(or options.envVarName + '_FILE'
) to load a file with a list of values expressed as environmental variables. This is the same format of ".env" files, and can be used with Docker secrets as well.
A ".env" file has a list of config values expressed as key=value
, separated by spacing characters (e.g. spaces or newlines). You can use single or double quotes to escape characters. Comments are not supported
Example of a ".env" file:
hello=world
quotes="required when using spaces"
escape='it\'s my life'
nested.value="updated value in a nested object"
Example of loading the file:
# Loading the .env file
SMCONFIG_FILE="path/to/.env" \
node myapp.js
# This can be used with Docker secrets too
SMCONFIG_FILE="/run/secrets/env" \
node myapp.js
Environment
The environment is determined by, in order:
- The value passed to the
env
parameter - The
process.env.NODE_ENV
environmental variable (when launching the application; for example:$ NODE_ENV=production node myapp.js
) - The environment that is configured for the hostname (see below)
- Fallback to the
default
environment
SMConfig.get(key)
// config is an instance of SMConfig
const databasePassword = config.get('databasePassword')
// You can access nested properties using the "dot notation"
const nested = config.get('database.credentials.password')
Returns the value for the key passed as argument, reading from the configuration for the environment.
SMConfig.environment
// config is an instance of SMConfig
const env = config.environment
The environment
property, which is read-only, contains the name of the environment being used by the application.
SMConfig.all
// config is an instance of SMConfig
const allConfiguration = config.all
The all
property, which is read-only, contains all the configuration variables for the current environment.
Hapi plugin
This module offers an optional plugin for Hapi (version 17 or higher required).
To use it, initialize the SMConfig object as normal, then register the plugin with Hapi passing the instance of SMConfig.
Example:
const SMConfig = require('smconfig')
const conf = new SMConfig(config, env, options)
await server.register({
plugin: require('smconfig/plugins/hapi'),
options: {config: conf}
})