flatiron/nconf — Issue #29: Memory Store in the chain of stores causes save to fail
Author: davidcl64
Created: 2012-01-29 15:39:56+00:00
State: open

I am currently using a memory store definition passed to child objects to keep readonly semantics on a global configuration file. However, calling save at the provider level results in the following exception:

TypeError: Object.keys called on non-object
at Function.keys (native)
at C:\util\build\node_modules\nconf\lib\nconf\common.js:96:12
at Array.forEach (native)
at Object.merge (C:\util\build\node_modules\nconf\lib\nconf\common.js:95:8)
at [object Object].save (C:\util\build\node_modules\nconf\lib\nconf\provider.js:425:19)
at...

Using a configuration hierarchy that looks something like:

provider = new nconf.Provider({
stores: [
{ name: 'workspace', type: 'file', file: 'workspace.json' },
{ name: 'buildId', type: 'file', file: 'buildId.json' },
{ name: 'global', type: 'memory', loadFrom: ['global.json'] }
]
});

Calling save on the provider in turn triggers this logic:

//
// If we don't have a callback and the current
// store is capable of saving synchronously
// then do so.
//
if (!callback) {
return common.merge(names.map(saveStoreSync));
}

The map function triggers saveStoreSync does the following:

//
// If the `store` doesn't have a `saveSync` method,
// just ignore it and continue.
//
return store.saveSync
? store.saveSync()
: null;

resulting in a null instead of the store object when the method saveSync is undefined on a particular store.

When common.merge is then called:

common.merge = function (objs) {
var store = new Memory();

objs.forEach(function (obj) {
Object.keys(obj).forEach(function (key) {
store.merge(key, obj[key]);
});
});

return store.store;
};

No check is done on the store prior to using it resulting in the exception listed above.

My workaround for now is to monkey patch the memory store with dummy save/saveSync methods.