Comparing version 0.4.6 to 0.5.0
/* | ||
* nconf.js: Top-level include for the nconf module | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -20,2 +20,14 @@ */ | ||
// | ||
// Setup all stores as lazy-loaded getters. | ||
// | ||
fs.readdirSync(__dirname + '/nconf/stores').forEach(function (file) { | ||
var store = file.replace('.js', ''), | ||
name = common.capitalize(store); | ||
nconf.__defineGetter__(name, function () { | ||
return require('./nconf/stores/' + store)[name]; | ||
}); | ||
}); | ||
// | ||
// Expose the various components included with nconf | ||
@@ -28,3 +40,2 @@ // | ||
nconf.formats = require('./nconf/formats'); | ||
nconf.stores = require('./nconf/stores'); | ||
nconf.Provider = Provider; | ||
nconf.Provider = Provider; |
/* | ||
* utils.js: Utility functions for the nconf module. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -6,0 +6,0 @@ */ |
/* | ||
* formats.js: Default formats supported by nconf | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -6,0 +6,0 @@ */ |
/* | ||
* provider.js: Abstraction providing an interface into pluggable configuration storage. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -9,7 +9,4 @@ */ | ||
var async = require('async'), | ||
common = require('./common'), | ||
stores = require('./stores'); | ||
common = require('./common'); | ||
// | ||
@@ -22,4 +19,2 @@ // ### function Provider (options) | ||
var Provider = exports.Provider = function (options) { | ||
var self = this; | ||
// | ||
@@ -29,49 +24,29 @@ // Setup default options for working with `stores`, | ||
// | ||
options = options || {}; | ||
this._overrides = options.overrides || null; | ||
this._argv = options.argv || false; | ||
this._env = options.env || false; | ||
this._reserved = Object.keys(Provider.prototype); | ||
this._stores = []; | ||
this.sources = []; | ||
// | ||
// Add the default `system` store for working with | ||
// `overrides`, `process.env`, `process.argv` and | ||
// a simple in-memory objects. | ||
// | ||
this.add('system', options); | ||
// | ||
// Add any stores passed in through the options | ||
// to this instance. | ||
// | ||
if (options.type) { | ||
this.add(options.type, options); | ||
} | ||
else if (options.store) { | ||
this.add(options.store.name || options.store.type, options.store); | ||
} | ||
else if (options.stores) { | ||
Object.keys(options.stores).forEach(function (name) { | ||
var store = options.stores[name]; | ||
self.add(store.name || name || store.type, store); | ||
}); | ||
} | ||
// | ||
// Add any read-only sources to this instance | ||
// | ||
if (options.source) { | ||
this.sources.push(this.create(options.source.type || options.source.name, options.source)); | ||
} | ||
else if (options.sources) { | ||
Object.keys(options.sources).forEach(function (name) { | ||
var source = options.sources[name]; | ||
self.sources.push(self.create(source.type || source.name || name, source)); | ||
}); | ||
} | ||
options = options || {}; | ||
this.stores = {}; | ||
this.sources = []; | ||
this.init(options); | ||
}; | ||
// | ||
// Define wrapper functions for using basic stores | ||
// in this instance | ||
// | ||
['argv', 'env', 'file'].forEach(function (type) { | ||
Provider.prototype[type] = function (options) { | ||
return this.add(type, options); | ||
}; | ||
}); | ||
// | ||
// Define wrapper functions for using | ||
// overrides and defaults | ||
// | ||
['defaults', 'overrides'].forEach(function (type) { | ||
Provider.prototype[type] = function (options) { | ||
return this.add('literal', options); | ||
}; | ||
}); | ||
// | ||
// ### function use (name, options) | ||
@@ -88,9 +63,2 @@ // #### @type {string} Type of the nconf store to use. | ||
Provider.prototype.use = function (name, options) { | ||
if (name === 'system') { | ||
return; | ||
} | ||
else if (this._reserved.indexOf(name) !== -1) { | ||
throw new Error('Cannot use reserved name: ' + name); | ||
} | ||
options = options || {}; | ||
@@ -105,3 +73,3 @@ var type = options.type || name; | ||
var store = this[name], | ||
var store = this.stores[name], | ||
update = store && !sameOptions(store); | ||
@@ -131,18 +99,13 @@ | ||
Provider.prototype.add = function (name, options) { | ||
if (this._reserved.indexOf(name) !== -1) { | ||
throw new Error('Cannot use reserved name: ' + name); | ||
} | ||
options = options || {}; | ||
var type = options.type || name; | ||
if (Object.keys(stores).indexOf(common.capitalize(type)) === -1) { | ||
if (!require('../nconf')[common.capitalize(type)]) { | ||
throw new Error('Cannot add store with unknown type: ' + type); | ||
} | ||
this[name] = this.create(type, options); | ||
this._stores.push(name); | ||
this.stores[name] = this.create(type, options); | ||
if (this[name].loadSync) { | ||
this[name].loadSync(); | ||
if (this.stores[name].loadSync) { | ||
this.stores[name].loadSync(); | ||
} | ||
@@ -161,11 +124,3 @@ | ||
Provider.prototype.remove = function (name) { | ||
if (this._reserved.indexOf(name) !== -1) { | ||
throw new Error('Cannot use reserved name: ' + name); | ||
} | ||
else if (!this[name]) { | ||
throw new Error('Cannot remove store that does not exist: ' + name); | ||
} | ||
delete this[name]; | ||
this._stores.splice(this._stores.indexOf(name), 1); | ||
delete this.stores[name]; | ||
return this; | ||
@@ -182,6 +137,46 @@ }; | ||
Provider.prototype.create = function (type, options) { | ||
return new stores[common.capitalize(type.toLowerCase())](options); | ||
return new (require('../nconf')[common.capitalize(type.toLowerCase())])(options); | ||
}; | ||
// | ||
// ### function init (options) | ||
// #### @options {Object} Options to initialize this instance with. | ||
// Initializes this instance with additional `stores` or `sources` in the | ||
// `options` supplied. | ||
// | ||
Provider.prototype.init = function (options) { | ||
var self = this; | ||
// | ||
// Add any stores passed in through the options | ||
// to this instance. | ||
// | ||
if (options.type) { | ||
this.add(options.type, options); | ||
} | ||
else if (options.store) { | ||
this.add(options.store.name || options.store.type, options.store); | ||
} | ||
else if (options.stores) { | ||
Object.keys(options.stores).forEach(function (name) { | ||
var store = options.stores[name]; | ||
self.add(store.name || name || store.type, store); | ||
}); | ||
} | ||
// | ||
// Add any read-only sources to this instance | ||
// | ||
if (options.source) { | ||
this.sources.push(this.create(options.source.type || options.source.name, options.source)); | ||
} | ||
else if (options.sources) { | ||
Object.keys(options.sources).forEach(function (name) { | ||
var source = options.sources[name]; | ||
self.sources.push(self.create(source.type || source.name || name, source)); | ||
}); | ||
} | ||
}; | ||
// | ||
// ### function get (key, callback) | ||
@@ -207,2 +202,3 @@ // #### @key {string} Key to retrieve for this instance. | ||
var current = 0, | ||
names = Object.keys(this.stores), | ||
self = this, | ||
@@ -212,5 +208,5 @@ response; | ||
async.whilst(function () { | ||
return typeof response === 'undefined' && current < self._stores.length; | ||
return typeof response === 'undefined' && current < names.length; | ||
}, function (next) { | ||
var store = self[self._stores[current]]; | ||
var store = self.stores[names[current]]; | ||
current++; | ||
@@ -304,5 +300,10 @@ | ||
Provider.prototype.load = function (callback) { | ||
var self = this, | ||
stores = this._stores.map(function (name) { return self[name] }); | ||
var self = this; | ||
function getStores () { | ||
return Object.keys(self.stores).map(function (name) { | ||
return self.stores[name]; | ||
}); | ||
} | ||
function loadStoreSync(store) { | ||
@@ -342,4 +343,5 @@ if (!store.loadSync) { | ||
if (data && typeof data === 'object') { | ||
Object.keys(data).forEach(function (key) { | ||
self.system.merge(key, data[key]); | ||
self.use('sources', { | ||
type: 'literal', | ||
store: data | ||
}); | ||
@@ -357,3 +359,3 @@ } | ||
mergeSources(loadBatch(self.sources)); | ||
return loadBatch(stores); | ||
return loadBatch(getStores()); | ||
} | ||
@@ -367,3 +369,3 @@ | ||
mergeSources(data); | ||
return loadBatch(stores, callback); | ||
return loadBatch(getStores(), callback); | ||
}); | ||
@@ -374,3 +376,3 @@ } | ||
? loadSources() | ||
: loadBatch(stores, callback); | ||
: loadBatch(getStores(), callback); | ||
}; | ||
@@ -391,19 +393,26 @@ | ||
var self = this; | ||
var self = this, | ||
names = Object.keys(this.stores); | ||
function saveStoreSync(name) { | ||
var store = self[name]; | ||
var store = self.stores[name]; | ||
if (!store.saveSync) { | ||
throw new Error('nconf store ' + store.type + ' has no saveSync() method'); | ||
} | ||
return store.saveSync(); | ||
// | ||
// If the `store` doesn't have a `saveSync` method, | ||
// just ignore it and continue. | ||
// | ||
return store.saveSync | ||
? store.saveSync() | ||
: null; | ||
} | ||
function saveStore(name, next) { | ||
var store = self[name]; | ||
var store = self.stores[name]; | ||
// | ||
// If the `store` doesn't have a `save` or saveSync` | ||
// method(s), just ignore it and continue. | ||
// | ||
if (!store.save && !store.saveSync) { | ||
return next(new Error('nconf store ' + store.type + ' has no save() method')); | ||
return next(); | ||
} | ||
@@ -422,6 +431,6 @@ | ||
if (!callback) { | ||
return common.merge(this._stores.map(saveStoreSync)); | ||
return common.merge(names.map(saveStoreSync)); | ||
} | ||
async.map(this._stores, saveStore, function (err, objs) { | ||
async.map(names, saveStore, function (err, objs) { | ||
return err ? callback(err) : callback(); | ||
@@ -442,2 +451,3 @@ }); | ||
callback = typeof args[args.length - 1] === 'function' && args.pop(), | ||
destructive = ['set', 'clear', 'merge'].indexOf(action) !== -1, | ||
self = this, | ||
@@ -447,4 +457,8 @@ response; | ||
function runAction (name, next) { | ||
var store = self[name] | ||
var store = self.stores[name]; | ||
if (destructive && store.readOnly) { | ||
return next(); | ||
} | ||
return store[action].length > syncLength | ||
@@ -456,3 +470,3 @@ ? store[action].apply(store, args.concat(next)) | ||
if (callback) { | ||
return async.forEach(self._stores, runAction, function (err) { | ||
return async.forEach(Object.keys(this.stores), runAction, function (err) { | ||
return err ? callback(err) : callback(); | ||
@@ -462,5 +476,13 @@ }); | ||
this._stores.forEach(function (name) { | ||
var store = self[name]; | ||
response = store[action].apply(store, args); | ||
Object.keys(this.stores).forEach(function (name) { | ||
if (typeof response === 'undefined') { | ||
var store = self.stores[name]; | ||
if (destructive && store.readOnly) { | ||
return; | ||
} | ||
response = store[action].apply(store, args); | ||
} | ||
}); | ||
@@ -472,28 +494,2 @@ | ||
// | ||
// ### @argv {boolean} | ||
// Gets or sets a property representing overrides which supercede all | ||
// other values for this instance. | ||
// | ||
Provider.prototype.__defineSetter__('overrides', function (val) { updateSystem.call(this, 'overrides', val) }); | ||
Provider.prototype.__defineGetter__('overrides', function () { return this._argv }); | ||
// | ||
// ### @argv {boolean} | ||
// Gets or sets a property indicating if we should wrap calls to `.get` | ||
// by checking `optimist.argv`. Can be a boolean or the pass-thru | ||
// options for `optimist`. | ||
// | ||
Provider.prototype.__defineSetter__('argv', function (val) { updateSystem.call(this, 'argv', val) }); | ||
Provider.prototype.__defineGetter__('argv', function () { return this._argv }); | ||
// | ||
// ### @env {boolean} | ||
// Gets or sets a property indicating if we should wrap calls to `.get` | ||
// by checking `process.env`. Can be a boolean or an Array of | ||
// environment variables to extract. | ||
// | ||
Provider.prototype.__defineSetter__('env', function (val) { updateSystem.call(this, 'env', val) }); | ||
Provider.prototype.__defineGetter__('env', function () { return this._env }); | ||
// | ||
// Throw the `err` if a callback is not supplied | ||
@@ -507,19 +503,2 @@ // | ||
throw err; | ||
} | ||
// | ||
// Helper function for working with the | ||
// default `system` store for providers. | ||
// | ||
function updateSystem(prop, value) { | ||
var system = this['system']; | ||
if (system[prop] === value) { | ||
return; | ||
} | ||
value = value || false; | ||
this['_' + prop] = value; | ||
system[prop] = value; | ||
system.loadSync(); | ||
} |
/* | ||
* file.js: Simple file storage engine for nconf files | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -84,29 +84,22 @@ */ | ||
if (!exists) { | ||
// | ||
// If the path we are attempting to load doesn't exist, create it | ||
// | ||
self.save({}, function (err) { | ||
self.store = {}; | ||
return callback(err, self.store); | ||
}); | ||
return callback(null, {}); | ||
} | ||
else { | ||
// | ||
// Else, the path exists, read it from disk | ||
// | ||
fs.readFile(self.file, function (err, data) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
try { | ||
self.store = self.format.parse(data.toString()); | ||
} | ||
catch (ex) { | ||
return callback(new Error("Error parsing your JSON configuration file.")); | ||
} | ||
callback(null, self.store); | ||
}); | ||
} | ||
// | ||
// Else, the path exists, read it from disk | ||
// | ||
fs.readFile(self.file, function (err, data) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
try { | ||
self.store = self.format.parse(data.toString()); | ||
} | ||
catch (ex) { | ||
return callback(new Error("Error parsing your JSON configuration file.")); | ||
} | ||
callback(null, self.store); | ||
}); | ||
}); | ||
@@ -116,5 +109,5 @@ }; | ||
// | ||
// ### function load (callback) | ||
// #### @callback {function} **Optional** Continuation to respond to when complete. | ||
// Attempts to load the data stored in `this.file` synchronously and responds appropriately. | ||
// ### function loadSync (callback) | ||
// Attempts to load the data stored in `this.file` synchronously | ||
// and responds appropriately. | ||
// | ||
@@ -125,6 +118,2 @@ File.prototype.loadSync = function () { | ||
if (!path.existsSync(self.file)) { | ||
// | ||
// If the path we are attempting to load doesn't exist, create it | ||
// | ||
self.saveSync({}); | ||
self.store = {}; | ||
@@ -131,0 +120,0 @@ data = {}; |
/* | ||
* memory.js: Simple memory storage engine for nconf configuration(s) | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -6,0 +6,0 @@ */ |
{ | ||
"name": "nconf", | ||
"description": "Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging.", | ||
"version": "0.4.6", | ||
"author": "Charlie Robbins <charlie.robbins@gmail.com>", | ||
"version": "0.5.0", | ||
"author": "Nodejitsu Inc. <info@nodejitsu.com>", | ||
"contributors": [ | ||
{ "name": "Charlie Robbins", "email": "charlie@nodejitsu.com" } | ||
], | ||
"repository": { | ||
@@ -21,4 +24,4 @@ "type": "git", | ||
"main": "./lib/nconf", | ||
"scripts": { "test": "vows test/*-test.js --spec" }, | ||
"scripts": { "test": "vows test/*-test.js test/**/*-test.js --spec" }, | ||
"engines": { "node": ">= 0.4.0" } | ||
} |
166
README.md
@@ -5,15 +5,3 @@ # nconf [![Build Status](https://secure.travis-ci.org/flatiron/nconf.png)](http://travis-ci.org/flatiron/nconf) | ||
## Installation | ||
### Installing npm (node package manager) | ||
``` | ||
curl http://npmjs.org/install.sh | sh | ||
``` | ||
### Installing nconf | ||
``` | ||
[sudo] npm install nconf | ||
``` | ||
## Getting started | ||
## Example | ||
Using nconf is easy; it is designed to be a simple key-value store with support for both local and remote storage. Keys are namespaced and delimited by `:`. Lets dive right into sample usage: | ||
@@ -26,5 +14,14 @@ | ||
// | ||
// Setup nconf to use the 'file' store and set a couple of values; | ||
// Setup nconf to use (in-order): | ||
// 1. Command-line arguments | ||
// 2. Environment variables | ||
// 3. A file located at 'path/to/config.json' | ||
// | ||
nconf.add('file', { file: 'path/to/your/config.json' }); | ||
nconf.argv() | ||
.env() | ||
.file({ file: 'path/to/config.json' }); | ||
// | ||
// Set a few variables on `nconf`. | ||
// | ||
nconf.set('database:host', '127.0.0.1'); | ||
@@ -37,3 +34,5 @@ nconf.set('database:port', 5984); | ||
// | ||
console.dir(nconf.get('database')); | ||
console.log('foo: ' + nconf.get('foo')); | ||
console.log('NODE_ENV: ' + nconf.get('NODE_ENV')); | ||
console.log('database: ' + nconf.get('database')); | ||
@@ -50,11 +49,59 @@ // | ||
If you run the above script: | ||
``` bash | ||
$ NODE_ENV=production sample.js --foo bar | ||
``` | ||
The output will be: | ||
``` | ||
foo: bar | ||
NODE_ENV: production | ||
database: { host: '127.0.0.1', port: 5984 } | ||
``` | ||
## Hierarchical configuration | ||
Configuration management can get complicated very quickly for even trivial applications running in production. `nconf` addresses this problem by enabling you to setup a hierarchy for different sources of configuration with some sane defaults (in-order): | ||
Configuration management can get complicated very quickly for even trivial applications running in production. `nconf` addresses this problem by enabling you to setup a hierarchy for different sources of configuration with no defaults. **The order in which you attach these configuration sources determines their priority in the hierarchy.** Lets take a look at the options available to you | ||
1. Manually set overrides | ||
2. Command-line arguments | ||
3. Environment variables | ||
4. Any additional user stores (in the order they were added) | ||
1. **nconf.argv(options)** Loads `process.argv` using optimist. If `options` is supplied it is passed along to optimist. | ||
2. **nconf.env(options)** Loads `process.env` into the hierarchy. | ||
3. **nconf.file(options)** Loads the configuration data at options.file into the hierarchy. | ||
4. **nconf.defaults(options)** Loads the data in options.store into the hierarchy. | ||
5. **nconf.overrides(options)** Loads the data in options.store into the hierarchy. | ||
A sane default for this could be: | ||
``` js | ||
var nconf = require('nconf'); | ||
// | ||
// 1. any overrides | ||
// | ||
nconf.overrides({ | ||
'always': 'be this value' | ||
}); | ||
// | ||
// 2. `process.env` | ||
// 3. `process.argv` | ||
// | ||
nconf.env().argv(); | ||
// | ||
// 4. Values in `config.json` | ||
// | ||
nconf.file({ file: 'config.json' }); | ||
// | ||
// 5. Any default values | ||
// | ||
nconf.defaults({ | ||
'if nothing else': 'use this value' | ||
}); | ||
``` | ||
## API Documentation | ||
The top-level of `nconf` is an instance of the `nconf.Provider` abstracts this all for you into a simple API. | ||
@@ -66,4 +113,4 @@ | ||
``` js | ||
nconf.add('user', { type: 'file', file: '/path/to/userconf.json' }); | ||
nconf.add('global', { type: 'file', file: '/path/to/globalconf.json' }); | ||
nconf.add('userconf', { type: 'file', file: '/path/to/userconf.json' }); | ||
``` | ||
@@ -93,26 +140,2 @@ | ||
## Working with Configuration | ||
`nconf` will traverse the set of stores that you have setup in-order to ensure that the value in the store of the highest priority is used. For example to setup following sample configuration: | ||
1. Command-line arguments | ||
2. Environment variables | ||
3. User configuration | ||
3. Global configuration | ||
``` js | ||
var nconf = require('nconf'); | ||
// | ||
// Read in command-line arugments and environment variables | ||
// | ||
nconf.argv = nconf.env = true; | ||
// | ||
// Setup the `user` store followed by the `global` store. Note that | ||
// order is significant in these operations. | ||
// | ||
nconf.add('user', { file: 'path/to/user-config.json' }); | ||
nconf.add('global', { file: 'path/to/global-config.json' }) | ||
``` | ||
## Storage Engines | ||
@@ -127,23 +150,31 @@ | ||
### System | ||
Based on the Memory store, but exposes hooks into manual overrides, command-line arguments, and environment variables (in that order of priority). Every instance of `nconf.Provider`, including the top-level `nconf` object itself already has a `System` store at the top-level, so configuring it only requires setting properties | ||
### Argv | ||
Responsible for loading the values parsed from `process.argv` by `optimist` into the configuration hierarchy. | ||
``` js | ||
// | ||
// `nconf.get(awesome)` will always return true regardless of | ||
// command-line arguments or environment variables. | ||
// Can optionally also be an object literal to pass to `optimist`. | ||
// | ||
nconf.overrides = { awesome: true }; | ||
nconf.argv(options); | ||
``` | ||
### Env | ||
Responsible for loading the values parsed from `process.env` into the configuration hierarchy. | ||
``` js | ||
// | ||
// Can also be an object literal to pass to `optimist`. | ||
// Can optionally also be an Array of values to limit process.env to. | ||
// | ||
nconf.argv = true; | ||
// | ||
// Can also be an array of variable names to restrict loading to. | ||
// | ||
nconf.env = true; | ||
nconf.env(['only', 'load', 'these', 'values', 'from', 'process.env']); | ||
``` | ||
### Literal | ||
Loads a given object literal into the configuration hierarchy. Both `nconf.defaults()` and `nconf.overrides()` use the Literal store. | ||
``` js | ||
nconf.defaults({ | ||
'some': 'default value' | ||
}); | ||
``` | ||
### File | ||
@@ -153,3 +184,3 @@ Based on the Memory store, but provides additional methods `.save()` and `.load()` which allow you to read your configuration to and from file. As with the Memory store, all method calls are synchronous with the exception of `.save()` and `.load()` which take callback functions. It is important to note that setting keys in the File engine will not be persisted to disk until a call to `.save()` is made. | ||
``` js | ||
nconf.use('file', { file: 'path/to/your/config.json' }); | ||
nconf.file({ file: 'path/to/your/config.json' }); | ||
``` | ||
@@ -181,2 +212,14 @@ | ||
## Installation | ||
### Installing npm (node package manager) | ||
``` | ||
curl http://npmjs.org/install.sh | sh | ||
``` | ||
### Installing nconf | ||
``` | ||
[sudo] npm install nconf | ||
``` | ||
## More Documentation | ||
@@ -197,3 +240,4 @@ There is more documentation available through docco. I haven't gotten around to making a gh-pages branch so in the meantime if you clone the repository you can view the docs: | ||
#### Author: [Charlie Robbins](http://nodejitsu.com) | ||
#### License: MIT | ||
[0]: http://github.com/indexzero/nconf | ||
[0]: http://github.com/indexzero/nconf-redis |
/* | ||
* common.js: Tests for common utility function in nconf. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -6,0 +6,0 @@ */ |
/* | ||
* data.js: Simple data fixture for configuration test. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -6,0 +6,0 @@ */ |
/* | ||
* default-argv.js: Test fixture for using optimist defaults with nconf. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
*/ | ||
var nconf = require('../../../lib/nconf'); | ||
var nconf = require('../../../lib/nconf').argv().env(); | ||
nconf.argv = true; | ||
process.stdout.write(nconf.get('something')); |
/* | ||
* nconf-change-argv.js: Test fixture for changing argv on the fly | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
*/ | ||
var nconf = require('../../../lib/nconf'); | ||
var nconf = require('../../../lib/nconf').argv(); | ||
nconf.argv = true; | ||
// | ||
@@ -16,4 +14,4 @@ // Remove 'badValue', 'evenWorse' and 'OHNOEZ' | ||
process.argv.splice(3, 3); | ||
nconf.system.loadArgv(); | ||
nconf.stores['argv'].loadArgv(); | ||
process.stdout.write(nconf.get('something')); | ||
/* | ||
* nconf-env.js: Test fixture for using process.env defaults with nconf. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
*/ | ||
var nconf = require('../../../lib/nconf'); | ||
var nconf = require('../../../lib/nconf').env(); | ||
nconf.env = true; | ||
process.stdout.write(nconf.get('SOMETHING')); |
/* | ||
* provider-argv.js: Test fixture for using optimist defaults with nconf. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -10,4 +10,4 @@ */ | ||
var provider = new (nconf.Provider)({ argv: true }); | ||
var provider = new (nconf.Provider)().argv(); | ||
process.stdout.write(provider.get('something')); |
/* | ||
* provider-argv.js: Test fixture for using process.env defaults with nconf. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -10,4 +10,4 @@ */ | ||
var provider = new (nconf.Provider)({ env: true }); | ||
var provider = new (nconf.Provider)().env(); | ||
process.stdout.write(provider.get('SOMETHING')); |
/* | ||
* helpers.js: Test helpers for nconf. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -46,4 +46,4 @@ */ | ||
spawn(process.argv[0], [options.script].concat(options.argv), { env: env }) | ||
.stdout.once('data', this.callback.bind(this, null)); | ||
var child = spawn('node', [options.script].concat(options.argv), { env: env }); | ||
child.stdout.once('data', this.callback.bind(this, null)); | ||
}, | ||
@@ -50,0 +50,0 @@ "should respond with the value passed into the script": function (_, data) { |
/* | ||
* file-store-test.js: Tests for the nconf File store. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -31,3 +31,3 @@ */ | ||
nconf.use('memory'); | ||
assert.instanceOf(nconf.memory, nconf.stores.Memory); | ||
assert.instanceOf(nconf.stores['memory'], nconf.Memory); | ||
} | ||
@@ -34,0 +34,0 @@ }, |
/* | ||
* file-store-test.js: Tests for the nconf File store. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -27,9 +27,9 @@ */ | ||
"should use a new instance of the store type": function (provider) { | ||
var old = provider.file; | ||
var old = provider.stores['file']; | ||
assert.equal(provider.file.file, files[0]); | ||
assert.equal(provider.stores.file.file, files[0]); | ||
provider.use('file', { file: files[1] }); | ||
assert.notStrictEqual(old, provider.file); | ||
assert.equal(provider.file.file, files[1]); | ||
assert.notStrictEqual(old, provider.stores.file); | ||
assert.equal(provider.stores.file.file, files[1]); | ||
} | ||
@@ -44,3 +44,3 @@ }, | ||
env: { SOMETHING: 'foobar' } | ||
}), | ||
}) | ||
}, | ||
@@ -60,2 +60,7 @@ "the default nconf provider": { | ||
argv: ['--something', 'badValue', 'evenWorse', 'OHNOEZ', 'foobar'] | ||
}), | ||
"when hierarchical 'argv' get": helpers.assertSystemConf({ | ||
script: path.join(fixturesDir, 'scripts', 'nconf-hierarchical-file-argv.js'), | ||
argv: ['--something', 'foobar'], | ||
env: { SOMETHING: true } | ||
}) | ||
@@ -72,3 +77,3 @@ } | ||
provider.merge(override); | ||
helpers.assertMerged(null, provider.file.store); | ||
helpers.assertMerged(null, provider.stores.file.store); | ||
} | ||
@@ -95,3 +100,2 @@ }, | ||
} | ||
}).export(module); | ||
}).export(module); |
/* | ||
* file-store-test.js: Tests for the nconf File store. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -13,3 +13,3 @@ */ | ||
nconf = require('../../lib/nconf'), | ||
data = require('../fixtures/data').data, | ||
data = require('../fixtures/data').data, | ||
store; | ||
@@ -19,30 +19,32 @@ | ||
"When using the nconf file store": { | ||
topic: function () { | ||
var filePath = path.join(__dirname, '..', 'fixtures', 'store.json'); | ||
fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); | ||
store = new nconf.stores.File({ file: filePath }); | ||
return null; | ||
}, | ||
"the load() method": { | ||
"with a valid JSON file": { | ||
topic: function () { | ||
store.load(this.callback); | ||
var filePath = path.join(__dirname, '..', 'fixtures', 'store.json'); | ||
fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); | ||
this.store = store = new nconf.File({ file: filePath }); | ||
return null; | ||
}, | ||
"should load the data correctly": function (err, data) { | ||
assert.isNull(err); | ||
assert.deepEqual(data, store.store); | ||
"the load() method": { | ||
topic: function () { | ||
this.store.load(this.callback); | ||
}, | ||
"should load the data correctly": function (err, data) { | ||
assert.isNull(err); | ||
assert.deepEqual(data, this.store.store); | ||
} | ||
} | ||
} | ||
}, | ||
"When using the nconf file store": { | ||
topic: function () { | ||
var filePath = path.join(__dirname, '..', 'fixtures', 'malformed.json'); | ||
store = new nconf.stores.File({ file: filePath }); | ||
return null; | ||
}, | ||
"the load() method with a malformed JSON config file": { | ||
"with a malformed JSON file": { | ||
topic: function () { | ||
store.load(this.callback.bind(null, null)); | ||
var filePath = path.join(__dirname, '..', 'fixtures', 'malformed.json'); | ||
this.store = new nconf.File({ file: filePath }); | ||
return null; | ||
}, | ||
"should respond with an error": function (ign, err) { | ||
assert.isTrue(!!err); | ||
"the load() method with a malformed JSON config file": { | ||
topic: function () { | ||
this.store.load(this.callback.bind(null, null)); | ||
}, | ||
"should respond with an error": function (_, err) { | ||
assert.isTrue(!!err); | ||
} | ||
} | ||
@@ -55,3 +57,3 @@ } | ||
var tmpPath = path.join(__dirname, '..', 'fixtures', 'tmp.json'), | ||
tmpStore = new nconf.stores.File({ file: tmpPath }); | ||
tmpStore = new nconf.File({ file: tmpPath }); | ||
return tmpStore; | ||
@@ -63,15 +65,15 @@ }, | ||
Object.keys(store.store).forEach(function (key) { | ||
tmpStore.set(key, store.store[key]); | ||
}); | ||
Object.keys(data).forEach(function (key) { | ||
tmpStore.set(key, data[key]); | ||
}); | ||
tmpStore.save(function () { | ||
fs.readFile(tmpStore.file, function (err, data) { | ||
return err ? that.callback(err) : that.callback(err, JSON.parse(data.toString())); | ||
fs.readFile(tmpStore.file, function (err, d) { | ||
return err ? that.callback(err) : that.callback(err, JSON.parse(d.toString())); | ||
}); | ||
}); | ||
}, | ||
"should save the data correctly": function (err, data) { | ||
"should save the data correctly": function (err, read) { | ||
assert.isNull(err); | ||
assert.deepEqual(data, store.store); | ||
assert.deepEqual(read, data); | ||
} | ||
@@ -115,3 +117,3 @@ } | ||
fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); | ||
return new (nconf.stores.File)({ | ||
return new (nconf.File)({ | ||
file: '.nconf' | ||
@@ -129,3 +131,3 @@ }) | ||
var filePath = this.filePath = path.join(__dirname, '..', 'fixtures', 'search-store.json'); | ||
return new (nconf.stores.File)({ | ||
return new (nconf.File)({ | ||
dir: path.dirname(filePath), | ||
@@ -132,0 +134,0 @@ file: 'search-store.json' |
/* | ||
* memory-store-test.js: Tests for the nconf Memory store. | ||
* | ||
* (C) 2011, Charlie Robbins | ||
* (C) 2011, Nodejitsu Inc. | ||
* | ||
@@ -15,3 +15,3 @@ */ | ||
"When using the nconf memory store": { | ||
topic: new nconf.stores.Memory(), | ||
topic: new nconf.Memory(), | ||
"the set() method": { | ||
@@ -18,0 +18,0 @@ "should respond with true": function (store) { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
243175
49
2031
234
16
3