
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Configue is a config library to easily customize your app from argv, env, files and more.
CONFIGUE ALL THE THINGS \o/
Configue is a node.js config library to easily customize your app from argv, env, files and more.
It defines a conventional workflow to load a config from environment variables, command line arguments, files, that you can easily configure and extend.
Configue builds up on nconf and its Hierarchical configuration system.
It defines a list of configuration steps that are executed in order. Every property defined on a steps will shadow the same key in the following steps.
Quoting nconf:
"The order in which you attach these configuration sources determines their priority in the hierarchy"
Here are the standard steps Configue does define:
overrides : properties that would take precedence on all other stepsargv : command line options--configue in argv if any.env : environment variablesfile : config filesdefaults : default objectsThe plugin loads the various configurations in order using predefined steps.
It starts by parsing argv then goes through the env and the files options and finishes by loading the default config objects if any. Hence why every option defined as an argument commandline will override defaults and environment variables.
If --configue option is specified, the config the specified file holds would
be loaded after the argv and before the env. This is to enable you to save
many options in many files, and specify at launch with options you want to use.
Just add configue has a dependency installing it with npm, or with yarn.
npm install --save configue
yarn add configue
To use Configue you need first to create an instance passing the option to the Configue(opts)
constructor. Resolving of the config is now done synchronously and automatically unless you specify
the defer: true option, or if you opt in for an async resolve.
In case of a problem with the configue options it will throw an Error.
See the following examples for concrete presentation.
const Configue = require('configue');
const configue = new Configue();
const who = configue.get('who', 'World');
console.log(`Hello ${who}`);
const Configue = require('configue');
const configue = new Configue({async: true});
configue.resolve().then(() => {
const who = configue.get('who', 'World');
console.log(`Hello ${who}`);
});
Async resolve is necessary for some advanced features like async hooks and shortstop protocols.
You can specify the who configue in different manners.
Here are some:
node basic.js --who=Woman
# configue through Env
export who=Man ; node basic.js
who=Human node basic.js
node basic.js --configue=my-who-conf.json
The full example is available in the examples folder.
You can retrieve values from the store in different manner, get is the most simple one.
get↥To retrieve a configue value, use the get method on the config holder.
It takes has argument the key of the argument. For nested value you need to
use : or . to deep access to value, or you can an array of keys.
It's also possible to specify a default value in case key is undefined.
configue.get('defined4sure');
configue.get('some:nested:value');
configue.get('some.other.nested.value');
configue.get(['yet', 'another', 'nested', 'value']);
configue.get('mightBeUndefined', 'default');
You can also retrieve a list of value with getAll, or the first non undefined value from a list with getFirst
configue.getAll('defined4sure', 'some:nested:value');
configue.getAll(['defined4sure', 'some:nested:value']);
configue.getAll(['some.other.nested.value', ['yet', 'another', 'nested', 'value']]);
configue.getFirst('defined4sure', 'some:nested:value');
configue.getFirst(['defined4sure', 'some:nested:value'], optionalDefaultValue);
When you can to retrieve several values in the same time you can forge object so that they have structure you need.
The two main methods are load and getObject
load by default return the whole merged config as an object. But you can give him a model that would be used
to craft an object. The model is a object whose leaves are configue keys, or array of configue key:
ex: {serverConfig: {host: 'app:server:host', port: 'PORT'}, ...}getObject that takes a list of key, and return an object formed by key / valuesconst {serverConfig} = configue.load({
serverConfig: {host: 'app:server:host', port: 'PORT'},
extraOptions: '...'
});
const {file, prefix} = configue.getObject('file', 'prefix');
There are case where the forged object are to be used several times, and you dont want to query them over and over.
To do that you can predefined models in the configuration. These would be populated once during automatic resolved,
and they would be made accessible under the _ key.
const configue = new Configue({
models: {
serverConfig: {host: 'app:server:host', port: 'PORT'},
otherModel: {a: 'a', b: '...'}
}
});
//...
console.log(configue._.serverConfig); // => host: ..., port: ...
One last way you can get config value is via the configue.template (aliased to configue.t).
This is a template function you can prefix a template string. The interpolated values will be keys of the
configue and then replaced by their value:
console.log(configue.t`I will say ${'salute'} to ${'who'}`);
// => I will say Hello to You
// (supposing called with --salute=Hello --who=You)
You can defined default values by passing a default object to the template method:
console.log(
configue.t({times: 2, who: 'World'})`I will say ${'salute'} to ${'who'} ${'times'} times`
);
// => I will say Hello to You 2 times
For ease of the the argv and env can be directly accessible from the configue instance:
console.log(configue.argv.host);
console.log(configue.env.HOME);
Note that values are neither parsed nor transformed.
The files key can contain a single object or an array of objects containing a file key containing the path to the config file.
The object can also reference a nconf plugin tasked with the formatting using the key format.
Starting from 1.0 the formatter to use can be automatically deduced for standard files. Supported extensions are
json, yaml/yml but also properties/ini and json5 In that case you just need to specify the name of the file.
const Configue = require('configue');
const configueOptions = {
disable: {argv: true},
files: [
{file: './config.json'},
{
file: './config.yaml',
format: require('nconf-yaml')
},
'my-own.properties'
]
};
const configue = new Configue(configueOptions);
Note that if only one file is needed, its path can be directly given as options.
Protocall(originally Shortstop) is a library that help transform json values by interpreting their content. Quoting documentation:
it enables the use of protocols and handlers to enable identification and special handling of json values.
For instance value with the standard env and file protocol,
env:MY_ENV_VARIABLE will be replaced with the value of MY_ENV_VARIABLE while value file:/some/path will be
resolved with the content of the given file.
For more details refer to the protocall project.
To enable it, you just need to have {async: true, protocall: true} in your Configue config object.
By default Configue comes empowered with the protocols from shortstop-handlers:
env, file, path, exec, base64, require.
You can customize behavior of protocall by passing a config object as option:
protocols options, by passing an object {$protocolName: $handler}baseDir for file, path, exec, require default handler. (default being current working directory)noDefaultProtocols option.preserveBuffer option.For an example of configuration refer to the following examples using this json file as part of the config.
You can provide options arguments to argv (yargsunderneath), and env in order to customize the behavior
around command line argument and environment variables.
For more in depth readings see nconf options here
const Configue = require('configue');
const configueOptions = {
argv: {
f: {
alias: 'file',
demandOption: true,
default: '/etc/passwd',
describe: 'x marks the spot',
type: 'string'
}
},
env: ['HOME', 'PWD'] // whitelist
};
const configue = new Configue(configueOptions);
It is possible to process the raw values you can get from the argv and env step, with the parse, separator
ignorePrefix, normalize and transform options.
First you can specify to parse values with the parse option. Argv and Env value will be then parse,
which is convenient to pass simple json from the command line.
A separator option is there to indicate the token that will be used to split a key and consider it as a nested value.
This affects both the argv and env step. The value can be either a string, or a regexp such as '__' or /__|--/
With ignorePrefix you can list of prefix for argv and env variable you want to be removed. This is particulary useful
with environment variables that are prefixed with your app name.
Also a normalize option enables you to make the variable names uniform with the same case, while using the idiomatic
case for the argv flag name and env variable. (for instance --my-var and MY_VAR).
This option accept as config the name of case function of lodash, the most useful being camelCase which will
transform our both variable into myVar as we would like name the javascript variable.
(other options are kebabCase, startCase, snakeCase,upperCase, lowerCase)
If you have more complex processing of the env/arg variable name or value, you can use the transform option,
which accept a function ({key, value}) => ({key:someKey, value:someValue}) that will be passed to nconf. (cf nconf doc)
This will happen after the ignore prefix, and before the case normalisation.
The argv and env steps can be skipped using the disable object in options.
const configue = new Configue({disable: {argv: true}});
// ...
There is no disabling for overrides, files and default; you just have to don't provide the matching option.
Every step (overrides, argv, env, files, defaults) has a post hook available.
Those can be defined using the postHooks key and accept a function that take nconf.
In async mode those hooks can be asynchronous by returning a Promise.
The special hooks first enables you to respectively apply a function on nconf at the very beginning.
const configue = new Configue({
postHooks: {
first: function first(nconf) {
// Your code here
},
overrides: function postOverrides(nconf) {
// Your code here
},
argv: function postArgv(nconf) {
// Your code here
}
}
});
// Your code here
If needed you can have your full custom configuration workflow,
simply by providing an object with the single key customWorkflow
attached to a function taking the nconf object, and a done callback.
const configueOptions = {
customWorkflow(nconf, done) {
// my own config setting
}
};
const configue = new Configue(configueOptions);
If you use a yargs instance, you can assign it to nconf._yargs so that argv
is directly accessible from `configue.argv
Thought Configue is usable without hapi, (it was originally just a _Hapi_ plugin), it can be easily loaded in hapi` to have the configue being easily accessible from
the server, or the request.
To do this, you need to register the plugin. It takes care to resolve the config if was not done due to defer.
const Hapi = require('hapi');
const Configue = require('configue');
const configue = new Configue({some: 'complex config with a model connexion'});
const server = new Hapi.Server();
server.connection(configue._.connexion); // note usage of the model connexion with port in it.
server.register({register: configue.plugin()}, err => {
// starting the server or else
// access to the config
const config = server.configue('some'); // => 'config'
const configGet = server.configue.get('some'); // => 'config'
// Any other call to server.configue.getAsync/getFirst/getAll/getObject/template/load
// ...
});
A more complete example is available in examples folder.
Note it's possible to provide to configue.plugin() a decorateName so that you use a custom accessor on server or request.
Warning: the original plugin is made for the pre 17 version of hapi. If you are using hapi@17 or beyond, please retrive the plugin with the plugin17()` method as you can see in the example server.
Configue can also be loaded into express via it's middleware you can obtain by configue.middleware() you just have
to feed to app.use()
A example is available in the examples folder.
Configue can be configured in two different way. Either using a config object or using a fluent builder.
Here is a recap of how the configuration should look like. All options are optional:
customWorkflow: a function manipulating the nconf. This option is exclusive of all othersargv: Config object for yargv, a map of config key with an object values (alias, demandOption, default,describe, type)env: The options for the nconf.env method that can be:
match, `whitelistdisable: A object with key argv and/or env attach to a boolean indicated whether the step should be disable.files: file or list of files. (object file, format)defaults: Object of key mapped to default values. (or array of them)overrides: Object of key mapped to overrides values.required: list of key that are required one way or anotherpostHooks: an object of (step: function hook)
step being one of first, overrides, argv, env, files defaultsparse: boolean to request parsing of argv/env valuetransform: a function to process argv and env valuesnormalize: the case name in which you want keys to be convertedignorePrefix: a prefix or list of them you want to be remove from key nameprotocall/shortstop: to activate and customize the protocall/shortstop protocols. (prefer protocall, shortstop is to be deprecated)async: to activate async mode which will defer resolvedefer: to defer automatic resolve in sync modeFor more details you can see the internals.schema in the configue-core.js file around the line 60
Instead to use the configuration object provided to the Configue constructor, you can use the fluent builder.
This consist in chaining a list of configuration methods before to retrieve the instance to a get method or via a
resolve method.
Here is a simple example:
const configue = Configue.defaults({a: 1, b: '2'})
.parse(true)
.normalize('camelCase')
.get();
You can provide a portion of option with the withOption method as you can see in this example using resolve:
Configue.defaults({a: 1, b: '2'})
.withOptions({parse: true, normalize: 'camelCase'})
.protocall(true)
.resolve(configue => {
// here goes your code
});
Here is the builder function list, the function name being the name of the key in he object config (except the postHooks function and withOptions):
argv, async, customWorkflow, defaults, overrides, disable, env, files, required, transform, parse, normalize, separator, protocall
and firstHook, overridesHook, argvHook, envHook, filesHook, defaultsHook, withOptions
FAQs
Configue is a config library to easily customize your app from argv, env, files and more.
The npm package configue receives a total of 2 weekly downloads. As such, configue popularity was classified as not popular.
We found that configue demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.