diff --git a/lib/nconf/provider.js b/lib/nconf/provider.js index d9bf022..a88e8ba 100644 --- a/lib/nconf/provider.js +++ b/lib/nconf/provider.js @@ -30,6 +30,7 @@ var Provider = exports.Provider = function (options) { this._envĀ  = options.env || false; this._reserved = Object.keys(Provider.prototype); this._stores = []; + this.sources = []; // // Add the default `system` store for working with @@ -38,6 +39,10 @@ var Provider = exports.Provider = function (options) { // this.add('system', options); + // + // Add any stores passed in through the options + // to this instance. + // if (options.type) { this.add(options.type, options); } @@ -47,7 +52,20 @@ var Provider = exports.Provider = function (options) { else if (options.stores) { Object.keys(options.stores).forEach(function (name) { var store = options.stores[name]; - self.add(store.name || store.type, store); + 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)); }); } }; @@ -122,6 +140,8 @@ Provider.prototype.add = function (name, options) { if (this[name].loadSync) { this[name].loadSync(); } + + return this; }; // @@ -141,6 +161,7 @@ Provider.prototype.remove = function (name) { delete this[name]; this._stores.splice(this._stores.indexOf(name), 1); + return this; }; // @@ -270,11 +291,11 @@ Provider.prototype.merge = function () { // Responds with an Object representing all keys associated in this instance. // Provider.prototype.load = function (callback) { - var self = this; + var self = this, + stores = this._stores.map(function (name) { return self[name] }) + .concat(this.sources); - function loadStoreSync(name) { - var store = self[name]; - + function loadStoreSync(store) { if (!store.loadSync) { throw new Error('nconf store ' + store.type + ' has no loadSync() method'); } @@ -282,9 +303,7 @@ Provider.prototype.load = function (callback) { return store.loadSync(); } - function loadStore(name, next) { - var store = self[name]; - + function loadStore(store, next) { if (!store.load && !store.loadSync) { return next(new Error('nconf store ' + store.type + ' has no load() method')); } @@ -300,10 +319,10 @@ Provider.prototype.load = function (callback) { // then do so. // if (!callback) { - return common.merge(this._stores.map(loadStoreSync)); + return common.merge(stores.map(loadStoreSync)); } - async.map(this._stores, loadStore, function (err, objs) { + async.map(stores, loadStore, function (err, objs) { return err ? callback(err) : callback(null, common.merge(objs)); }); }; diff --git a/test/provider-test.js b/test/provider-test.js index 1dc3b56..1ac9b11 100644 --- a/test/provider-test.js +++ b/test/provider-test.js @@ -64,6 +64,23 @@ vows.describe('nconf/provider').addBatch({ provider.merge(override); helpers.assertMerged(null, provider.file.store); } + }, + "when sources are passed in": { + topic: new nconf.Provider({ + sources: { + user: { + type: 'file', + file: files[0] + }, + global: { + type: 'file', + file: files[1] + } + } + }), + "should have the result merged in": function (provider) { + helpers.assertMerged(null, provider.load()); + } } } }