Merge objects if necessary when traversing stores on get()
This commit is contained in:
parent
6b1b019353
commit
26d81e8dca
5 changed files with 90 additions and 6 deletions
|
@ -218,7 +218,8 @@ Provider.prototype.get = function (key, callback) {
|
||||||
var current = 0,
|
var current = 0,
|
||||||
names = Object.keys(this.stores),
|
names = Object.keys(this.stores),
|
||||||
self = this,
|
self = this,
|
||||||
response;
|
response,
|
||||||
|
mergeObjs = [];
|
||||||
|
|
||||||
async.whilst(function () {
|
async.whilst(function () {
|
||||||
return typeof response === 'undefined' && current < names.length;
|
return typeof response === 'undefined' && current < names.length;
|
||||||
|
@ -233,13 +234,30 @@ Provider.prototype.get = function (key, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
response = value;
|
response = value;
|
||||||
|
|
||||||
|
// Merge objects if necessary
|
||||||
|
if (typeof response === 'object' && !Array.isArray(response)) {
|
||||||
|
mergeObjs.push(response);
|
||||||
|
response = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
response = store.get(key);
|
response = store.get(key);
|
||||||
|
|
||||||
|
// Merge objects if necessary
|
||||||
|
if (typeof response === 'object' && !Array.isArray(response)) {
|
||||||
|
mergeObjs.push(response);
|
||||||
|
response = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
|
if (!err && mergeObjs.length) {
|
||||||
|
response = common.merge(mergeObjs.reverse());
|
||||||
|
}
|
||||||
return err ? callback(err) : callback(null, response);
|
return err ? callback(err) : callback(null, response);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -475,7 +493,8 @@ Provider.prototype._execute = function (action, syncLength /* [arguments] */) {
|
||||||
callback = typeof args[args.length - 1] === 'function' && args.pop(),
|
callback = typeof args[args.length - 1] === 'function' && args.pop(),
|
||||||
destructive = ['set', 'clear', 'merge'].indexOf(action) !== -1,
|
destructive = ['set', 'clear', 'merge'].indexOf(action) !== -1,
|
||||||
self = this,
|
self = this,
|
||||||
response;
|
response,
|
||||||
|
mergeObjs = [];
|
||||||
|
|
||||||
function runAction (name, next) {
|
function runAction (name, next) {
|
||||||
var store = self.stores[name];
|
var store = self.stores[name];
|
||||||
|
@ -505,9 +524,19 @@ Provider.prototype._execute = function (action, syncLength /* [arguments] */) {
|
||||||
}
|
}
|
||||||
|
|
||||||
response = store[action].apply(store, args);
|
response = store[action].apply(store, args);
|
||||||
|
|
||||||
|
// Merge objects if necessary
|
||||||
|
if (action === 'get' && typeof response === 'object' && !Array.isArray(response)) {
|
||||||
|
mergeObjs.push(response);
|
||||||
|
response = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (mergeObjs.length) {
|
||||||
|
response = common.merge(mergeObjs.reverse());
|
||||||
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ vows.describe('nconf').addBatch({
|
||||||
"literal vars": {
|
"literal vars": {
|
||||||
"are present": function () {
|
"are present": function () {
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
assert.equal(nconf.get(key), data[key]);
|
assert.deepEqual(nconf.get(key), data[key]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
8
test/fixtures/merge/file1.json
vendored
8
test/fixtures/merge/file1.json
vendored
|
@ -7,6 +7,10 @@
|
||||||
"candy": {
|
"candy": {
|
||||||
"something": "file1",
|
"something": "file1",
|
||||||
"something1": true,
|
"something1": true,
|
||||||
"something2": true
|
"something2": true,
|
||||||
|
"something5": {
|
||||||
|
"first": 1,
|
||||||
|
"second": 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
test/fixtures/scripts/nconf-hierarchical-load-merge.js
vendored
Normal file
18
test/fixtures/scripts/nconf-hierarchical-load-merge.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* nconf-hierarchical-load-merge.js: Test fixture for loading and merging nested objects across stores.
|
||||||
|
*
|
||||||
|
* (C) 2012, Nodejitsu Inc.
|
||||||
|
* (C) 2012, Michael Hart
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
var path = require('path'),
|
||||||
|
nconf = require('../../../lib/nconf');
|
||||||
|
|
||||||
|
nconf.argv()
|
||||||
|
.file(path.join(__dirname, '..', 'merge', 'file1.json'));
|
||||||
|
|
||||||
|
process.stdout.write(JSON.stringify({
|
||||||
|
apples: nconf.get('apples'),
|
||||||
|
candy: nconf.get('candy')
|
||||||
|
}));
|
|
@ -75,6 +75,39 @@ vows.describe('nconf/hierarchy').addBatch({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"configured with .argv(), .file() and invoked with nested command line options": {
|
||||||
|
topic: function () {
|
||||||
|
var script = path.join(__dirname, 'fixtures', 'scripts', 'nconf-hierarchical-load-merge.js'),
|
||||||
|
argv = ['--candy:something', 'foo', '--candy:something5:second', 'bar'],
|
||||||
|
that = this,
|
||||||
|
data = '',
|
||||||
|
child;
|
||||||
|
|
||||||
|
child = spawn('node', [script].concat(argv));
|
||||||
|
|
||||||
|
child.stdout.on('data', function (d) {
|
||||||
|
data += d;
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', function() {
|
||||||
|
that.callback(null, data);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"should merge nested objects ": function (err, data) {
|
||||||
|
assert.deepEqual(JSON.parse(data), {
|
||||||
|
apples: true,
|
||||||
|
candy: {
|
||||||
|
something: 'foo',
|
||||||
|
something1: true,
|
||||||
|
something2: true,
|
||||||
|
something5: {
|
||||||
|
first: 1,
|
||||||
|
second: 'bar'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).export(module);
|
}).export(module);
|
||||||
|
|
Loading…
Reference in a new issue