Socket
Socket
Sign inDemoInstall

nconf

Package Overview
Dependencies
17
Maintainers
3
Versions
38
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.11.3 to 1.0.0-beta.0

13

CHANGELOG.md
v0.11.0 / Mon, 23 Nov 2020
==========================
* [4122731](https://github.com/projects/nconf/commit/4122731) 0.11.0 (`Matt Hamann`)
* [56794d1](https://github.com/projects/nconf/commit/56794d1) chore: upgrade deps to fix security vulns (`Matt Hamann`)
v0.10.0 / Mon, 18 Dec 2017
==========================
* [0ef652e](https://github.com/projects/nconf/commit/0ef652e) 0.10.0 (`Matt Hamann`)
* [01f25fa](https://github.com/projects/nconf/commit/01f25fa) Regex as env separator (#288) (`Adrien Becchis`)
* [16667be](https://github.com/projects/nconf/commit/16667be) Argv store separator (#291) (`Adrien Becchis`)
v0.9.1 / Fri, 3 Nov 2017
========================
* [bac910a](https://github.com/projects/nconf/commit/bac910a) 0.9.1 (`Matt Hamann`)
* [806f1b1](https://github.com/projects/nconf/commit/806f1b1) 0.9.1 (`Matt Hamann`)
* [2bdf7e1](https://github.com/projects/nconf/commit/2bdf7e1) Clean Argv Store options (#290) (`Adrien Becchis`)

@@ -17,0 +6,0 @@ * [b9321b2](https://github.com/projects/nconf/commit/b9321b2) transformer can now return an undefined key (#289) (`Adrien Becchis`)

10

lib/nconf/provider.js

@@ -237,4 +237,4 @@ /*

async.whilst(function () {
return typeof response === 'undefined' && current < names.length;
async.whilst(function (cb) {
cb(null, typeof response === 'undefined' && current < names.length);
}, function (next) {

@@ -316,4 +316,4 @@ var store = self.stores[names[current]];

async.whilst(function() {
return !result && keyIndex < keys.length;
async.whilst(function(cb) {
cb(null, !result && keyIndex < keys.length);
}, function(next) {

@@ -368,3 +368,3 @@ var key = keys[keyIndex];

} else {
return true;
return this;
}

@@ -371,0 +371,0 @@

@@ -23,11 +23,14 @@ /*

this.type = 'argv';
this.readOnly = true;
this.readOnly = options.readOnly !== undefined? options.readOnly : true;
this.options = options;
this.usage = usage;
if(typeof options.parseValues === 'boolean') {
this.parseValues = options.parseValues;
delete options.parseValues;
if(typeof options.readOnly === 'boolean') {
this.readOnly = options.readOnly;
delete options.readOnly;
// FIXME; should not mutate options!!!!
} else {
this.parseValues = false;
this.readOnly = true;
}
if (typeof options.transform === 'function') {

@@ -39,8 +42,2 @@ this.transform = options.transform;

}
if (typeof options.separator === 'string' || options.separator instanceof RegExp) {
this.separator = options.separator;
delete options.separator;
} else {
this.separator = '';
}
};

@@ -87,3 +84,9 @@

this.readOnly = false;
var tempWrite = false;
if(this.readOnly) {
this.readOnly = false;
tempWrite = true;
}
Object.keys(argv).forEach(function (key) {

@@ -97,8 +100,3 @@ var val = argv[key];

if (self.separator) {
self.set(common.key.apply(common, key.split(self.separator)), val);
}
else {
self.set(key, val);
}
self.set(key, val);
}

@@ -110,3 +108,5 @@ });

this.readOnly = true;
if (tempWrite) {
this.readOnly = true;
}
return this.store;

@@ -113,0 +113,0 @@ };

@@ -23,5 +23,4 @@ /*

this.type = 'env';
this.readOnly = true;
this.readOnly = options.readOnly !== undefined ? options.readOnly : true;
this.whitelist = options.whitelist || [];
this.separator = options.separator || '';
this.lowerCase = options.lowerCase || false;

@@ -39,5 +38,2 @@ this.parseValues = options.parseValues || false;

}
if (typeof(options) === 'string' || options instanceof RegExp) {
this.separator = options;
}
};

@@ -77,3 +73,9 @@

this.readOnly = false;
var tempWrite = false;
if(this.readOnly) {
this.readOnly = false;
tempWrite = true;
}
Object.keys(env).filter(function (key) {

@@ -90,3 +92,3 @@ if (self.match && self.whitelist.length) {

}).forEach(function (key) {
var val = env[key];

@@ -98,13 +100,10 @@

if (self.separator) {
self.set(common.key.apply(common, key.split(self.separator)), val);
}
else {
self.set(key, val);
}
self.set(key, val);
});
this.readOnly = true;
if (tempWrite) {
this.readOnly = true;
}
return this.store;
};

@@ -8,6 +8,7 @@ /*

var fs = require('fs'),
var os = require('os'),
fs = require('fs'),
path = require('path'),
util = require('util'),
Secure = require('secure-keys'),
crypto = require('crypto'),
formats = require('../formats'),

@@ -40,2 +41,3 @@ Memory = require('./memory').Memory;

|| 2;
this.eol = !(options.eol === false);

@@ -55,8 +57,2 @@ if (this.secure) {

}
this.keys = new Secure({
secret: this.secure.secret,
alg: this.secure.alg,
format: this.format
});
}

@@ -85,3 +81,3 @@

// ### function saveToFile (path, value, callback)
// #### @path {string} The path to the file where we save the configuration to
// #### @path {string} The path to the file where we save the configuration to
// #### @format {Object} Optional formatter, default behing the one of the store

@@ -192,6 +188,18 @@ // #### @callback {function} Continuation to respond to when complete.

if (this.secure) {
data = this.keys.encrypt(data);
var self = this;
data = Object.keys(data).reduce(function (acc, key) {
var value = format.stringify(data[key]);
var iv = crypto.randomBytes(16);
var cipher = crypto.createCipheriv(self.secure.alg, self.secure.secret, iv);
var ciphertext = cipher.update(value, 'utf8', 'hex');
ciphertext += cipher.final('hex');
acc[key] = { alg: self.secure.alg, value: ciphertext, iv: iv.toString('hex') };
return acc;
}, {});
}
return format.stringify(data, null, this.spacing);
var stringified = format.stringify(data, null, this.spacing);
var needsEOL = this.eol && stringified.slice(-1) !== os.EOL;
return stringified + (needsEOL ? os.EOL : '');
};

@@ -207,7 +215,20 @@

if (!this.secure) {
return parsed;
if (this.secure) {
var self = this;
parsed = Object.keys(parsed).reduce(function (acc, key) {
var value = parsed[key];
if (!value.iv) {
throw new Error('Your encrypted file is outdated (encrypted without iv). Please re-encrypt your file using a pre-v1 release of nconf, v0.10 or above.');
}
let decipher = crypto.createDecipheriv(value.alg, self.secure.secret, Buffer.from(value.iv, 'hex'));
var plaintext = decipher.update(value.value, 'hex', 'utf8');
plaintext += decipher.final('utf8');
acc[key] = self.format.parse(plaintext);
return acc;
}, {});
}
return this.keys.decrypt(parsed);
return parsed;

@@ -214,0 +235,0 @@ };

@@ -8,4 +8,12 @@ /*

var common = require('../common');
const common = require('../common');
const DEFAULT_ACCESS_SEPARATOR = ':';
const DEFAULT_INPUT_SEPARATOR = '__';
// Helper function for preparing a string for regex matching
function escapeRegExp(string) {
return typeof string === 'string' && string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
//

@@ -26,5 +34,11 @@ // ### function Memory (options)

this.loadFrom = options.loadFrom || null;
this.logicalSeparator = options.logicalSeparator || ':';
this.accessSeparator = options.accessSeparator || DEFAULT_ACCESS_SEPARATOR;
this.inputSeparator = options.inputSeparator || DEFAULT_INPUT_SEPARATOR;
this.parseValues = options.parseValues || false;
this.disableDefaultAccessSeparator = options.disableDefaultAccessSeparator || false;
if (typeof(options) === 'string' || options instanceof RegExp) {
this.inputSeparator = options;
}
if (this.loadFrom) {

@@ -35,2 +49,19 @@ this.store = common.loadFilesSync(this.loadFrom);

Memory.prototype._normalizeKey = function (key) {
let inputSeparator = this.inputSeparator;
if (inputSeparator instanceof RegExp) {
inputSeparator = inputSeparator.source;
} else {
inputSeparator = escapeRegExp(inputSeparator);
}
let separatorRegexStr = `${escapeRegExp(this.accessSeparator)}|${inputSeparator}`;
if (!this.disableDefaultAccessSeparator) {
separatorRegexStr += `|${DEFAULT_ACCESS_SEPARATOR}`;
}
const separatorRegEx = new RegExp(separatorRegexStr, 'g');
return key && key.replace(separatorRegEx, this.accessSeparator);
}
//

@@ -43,3 +74,3 @@ // ### function get (key)

var target = this.store,
path = common.path(key, this.logicalSeparator);
path = common.path(this._normalizeKey(key), this.accessSeparator);

@@ -73,3 +104,3 @@ //

var target = this.store,
path = common.path(key, this.logicalSeparator);
path = common.path(this._normalizeKey(key), this.accessSeparator);

@@ -128,3 +159,3 @@ if (path.length === 0) {

value = target,
path = common.path(key, this.logicalSeparator);
path = common.path(key, this.accessSeparator);

@@ -177,3 +208,3 @@ //

target = this.store,
path = common.path(key, this.logicalSeparator),
path = common.path(key, this.accessSeparator),
fullKey = key;

@@ -212,3 +243,3 @@

return Object.keys(value).every(function (nested) {
return self.merge(common.keyed(self.logicalSeparator, fullKey, nested), value[nested]);
return self.merge(common.keyed(self.accessSeparator, fullKey, nested), value[nested]);
});

@@ -215,0 +246,0 @@ };

{
"name": "nconf",
"description": "Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging.",
"version": "0.11.3",
"version": "1.0.0-beta.0",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",

@@ -22,21 +22,23 @@ "contributors": [

"dependencies": {
"async": "^1.4.0",
"ini": "^2.0.0",
"secure-keys": "^1.0.0",
"yargs": "^16.1.1"
"yargs": "^17.0.0"
},
"devDependencies": {
"coveralls": "^3.1.0",
"eslint": "^4.9.0",
"istanbul": "^0.4.5",
"nconf-yaml": "^1.0.2",
"vows": "^0.8.3"
"async": "^3.0.0",
"coveralls": "^3.0.2",
"eslint": "^7.0.0",
"istanbul": "^0.4.1",
"jest": "^27.0.0",
"nconf-yaml": "^1.0.2"
},
"main": "./lib/nconf",
"scripts": {
"test": "vows test/*-test.js test/**/*-test.js --spec",
"cover": "istanbul cover vows -- test/*-test.js test/**/*-test.js --spec",
"test": "jest --verbose",
"cover": "jest --coverage",
"coveralls": "cat coverage/lcov.info | coveralls",
"lint": "eslint ."
},
"files": [
"lib"
],
"engines": {

@@ -43,0 +45,0 @@ "node": ">= 0.4.0"

@@ -11,4 +11,4 @@ # nconf

``` js
var fs = require('fs'),
nconf = require('nconf');
// sample.js
var nconf = require('nconf');

@@ -43,3 +43,3 @@ //

nconf.save(function (err) {
fs.readFile('path/to/your/config.json', function (err, data) {
require('fs').readFile('path/to/your/config.json', function (err, data) {
console.dir(JSON.parse(data.toString()))

@@ -50,6 +50,6 @@ });

If you run the above script:
If you run the below script:
``` bash
$ NODE_ENV=production sample.js --foo bar
$ NODE_ENV=production node sample.js --foo bar
```

@@ -130,3 +130,3 @@

``` js
nconf.add('supplied', { type: 'literal', store: { 'some': 'config' });
nconf.add('supplied', { type: 'literal', store: { 'some': 'config' } });
nconf.add('user', { type: 'file', file: '/path/to/userconf.json' });

@@ -137,3 +137,3 @@ nconf.add('global', { type: 'file', file: '/path/to/globalconf.json' });

### nconf.any(names, callback)
Given a set of key names, gets the value of the first key found to be truthy. The key names can be given as separate arguments
Given a set of key names, gets the value of the first key found to be truthy. The key names can be given as separate arguments
or as an array. If the last argument is a function, it will be called with the result; otherwise, the value is returned.

@@ -188,3 +188,21 @@

```
You can also chain `.required()` calls when needed. for example when a configuration depends on another configuration store
```js
config
.argv()
.env()
.required([ 'STAGE']) //here you should have STAGE otherwise throw an error
.file( 'stage', path.resolve( 'configs', 'stages', config.get( 'STAGE' ) + '.json' ) )
.required([ 'OAUTH:redirectURL']) // here you should have OAUTH:redirectURL, otherwise throw an error
.file( 'oauth', path.resolve( 'configs', 'oauth', config.get( 'OAUTH:MODE' ) + '.json' ) )
.file( 'app', path.resolve( 'configs', 'app.json' ) )
.required([ 'LOGS_MODE']) // here you should haveLOGS_MODE, otherwise throw an error
.add( 'logs', {
type: 'literal',
store: require( path.resolve( 'configs', 'logs', config.get( 'LOGS_MODE' ) + '.js') )
} )
.defaults( defaults );
```
## Storage Engines

@@ -195,2 +213,6 @@

All built-in storage engines inherit from the Memory store.
Basic usage:
``` js

@@ -200,2 +222,15 @@ nconf.use('memory');

#### Options
The options defined below apply to all storage engines that inherit from Memory.
##### `accessSeparator: string` (default: `':'`)
Defines the separator used to get or set data using the `get()` and `set()` methods. Even if this is changed, the default "colon" separator will be available unless explicitly disabled (see `disableDefaultAccessSeparator`).
##### `inputSeparator: string` (default: `'__'`)
This option is used by the `argv` and `env` storage engines when loading values. Since most systems only allow dashes, underscores, and alphanumeric characters in environment variables and command line arguments, the `inputSeparator` provides a mechanism for loading hierarchical values from these sources.
##### `disableDefaultAccessSeparator: {true|false}` (default: `false`)
Disables the default access separator of `':'`, which is always available otherwise. This is mainly used to preserve legacy behavior. It can also be used to set keys that contain the default separator (e.g. `{ 'some:long:key' : 'some value' }`).
### Argv

@@ -214,3 +249,3 @@ Responsible for loading the values parsed from `process.argv` by `yargs` into the configuration hierarchy. See the [yargs option docs](https://github.com/bcoe/yargs#optionskey-opt) for more on the option format.

The input `obj` contains two properties passed in the following format:
```
``` js
{

@@ -224,3 +259,3 @@ key: '<string>',

The function may return either an object in the asme format as the input or a value that evaluates to false.
The function may return either an object in the same format as the input or a value that evaluates to false.
If the return value is falsey, the entry will be dropped from the store, otherwise it will replace the original key/value.

@@ -289,3 +324,3 @@

The input `obj` contains two properties passed in the following format:
```
``` js
{

@@ -304,2 +339,5 @@ key: '<string>',

#### `readOnly: {true|false}` (default: `true`)
Allow values in the env store to be updated in the future. The default is to not allow items in the env store to be updated.
#### Examples

@@ -314,3 +352,3 @@

//
// Can also specify a separator for nested keys (instead of the default ':')
// Can also specify an input separator for nested keys
//

@@ -322,4 +360,4 @@ nconf.env('__');

//
// Can also lowerCase keys.
// Especially handy when dealing with environment variables which are usually
// Can also lowerCase keys.
// Especially handy when dealing with environment variables which are usually
// uppercased while argv are lowercased.

@@ -339,3 +377,3 @@ //

nconf.env({
separator: '__',
inputSeparator: '__',
match: /^whatever_matches_this_will_be_whitelisted/

@@ -394,13 +432,15 @@ whitelist: ['database__host', 'only', 'load', 'these', 'values', 'if', 'whatever_doesnt_match_but_is_whitelisted_gets_loaded_too'],

This will encrypt each key using [`crypto.createCipher`](https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password), defaulting to `aes-256-ctr`. The encrypted file contents will look like this:
This will encrypt each key using [`crypto.createCipheriv`](https://nodejs.org/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options), defaulting to `aes-256-ctr`. The encrypted file contents will look like this:
```
``` js
{
"config-key-name": {
"alg": "aes-256-ctr", // cipher used
"value": "af07fbcf" // encrypted contents
"value": "af07fbcf", // encrypted contents
"iv": "49e7803a2a5ef98c7a51a8902b76dd10" // initialization vector
},
"another-config-key": {
"alg": "aes-256-ctr", // cipher used
"value": "e310f6d94f13" // encrypted contents
"value": "e310f6d94f13", // encrypted contents
"iv": "b654e01aed262f37d0acf200be193985" // initialization vector
},

@@ -407,0 +447,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with âšĄïž by Socket Inc