Skip to content

Commit

Permalink
feat(config): helper to overwrite and extend configuration
Browse files Browse the repository at this point in the history
This allows to parse a url from an url property and as well to overwrite and extend
variables as needed.
To pass in url as normal value an object is needed like the following: { url: { value: "http://example.com } }.

Fixes #349
Fixes db-migrate/pg#8
Fixes #488
Fixes #463
  • Loading branch information
wzrdtales committed Aug 13, 2017
1 parent ed9be93 commit d23c333
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 8 deletions.
42 changes: 41 additions & 1 deletion lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,14 @@ function walkConfig(level) {
return level;
}

exports.loadObject = function(config, currentEnv) {
exports.loadObject = function(_config, currentEnv) {
var out = new Config();
// do not overwrite the users config
var config = JSON.parse(JSON.stringify(_config));

for (var env in config) {


if (config[env].ENV) {
if(!process.env[config[env].ENV])
log.verbose('Environment variable ' + config[env].ENV + ' is empty!');
Expand All @@ -122,6 +126,42 @@ exports.loadObject = function(config, currentEnv) {
config[env] = walkConfig(config[env]);
out[env] = config[env];
}

if(typeof(config[env].url) === 'string') {

config[env] = Object.assign(
config[env],
exports.loadUrl(config[env].url, env)[env]
);
delete config[env].url;
}
else if(config[env].url && config[env].url.value) {

config[env].url = config[env].url.value;
}

if(config[env].overwrite || config[env].addIfNotExists) {

var overwrite = config[env].overwrite || {};

if(config[env].addIfNotExists) {

var addIfNotExists = config[env].addIfNotExists;
Object.keys(addIfNotExists).filter(function(key) {
return !overwrite[key] && !config[env][key];
}).forEach(function(key) {
config[env][key] = addIfNotExists[key];
});

delete config[env].addIfNotExists;
}

Object.keys(overwrite).forEach(function(key) {
config[env][key] = overwrite[key];
});

delete config[env].overwrite;
}
}

if(currentEnv) {
Expand Down
181 changes: 174 additions & 7 deletions test/config_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var Lab = require('lab');
var lab = exports.lab = Lab.script();
var config = require('../lib/config');
var path = require('path');
var sinon = require('sinon');

var _configLoad = config.load;
var _configLoadUrl = config.loadUrl;
Expand Down Expand Up @@ -160,18 +161,184 @@ lab.experiment('config', function() {
config.load = _configLoad;
config.loadUrl = _configLoadUrl;

lab.test('should something', function(done, cleanup) {

cleanup(function(next) {

delete require.cache[require.resolve('../lib/config')];
next();
});
lab.test('should something', function(done) {

Code.expect(
config.load.bind(this, configPath, 'dev')
).to.not.throw;
done();
});
});

lab.experiment('loading a url from url property', function() {


lab.test('should export a valid config',
function(done) {

var databaseUrl = {
'dev': {
'url': 'postgres://uname:[email protected]/dbname'
}
};
var cfg = config.loadObject(databaseUrl, 'dev');

Code.expect(cfg.getCurrent).to.exists();
var current = cfg.getCurrent();
Code.expect(current.env).to.equal('dev');
Code.expect(current.settings.url).to.not.exists();
Code.expect(current.settings.driver).to.equal('postgres');
Code.expect(current.settings.user).to.equal('uname');
Code.expect(current.settings.password).to.equal('pw');
Code.expect(current.settings.host).to.equal('server.com');
Code.expect(current.settings.database).to.equal('dbname');

done();
});

lab.test('should export the value if specified in suboject',
function(done) {

var databaseUrl = {
'dev': {
'url': {
'value': 'http://example.com'
}
}
};
var cfg = config.loadObject(databaseUrl, 'dev');

Code.expect(cfg.getCurrent).to.exists();
var current = cfg.getCurrent();
Code.expect(current.env).to.equal('dev');
Code.expect(current.settings.url).to.equal('http://example.com');

done();
});
});

lab.experiment('loading from an URL and overwriting it', function() {

var databaseUrl = {
'dev': {
'url': 'postgres://uname:[email protected]/dbname',
'overwrite': {
'ssl': true
}
}
};

var cfg = config.loadObject(databaseUrl, 'dev');

lab.test('should export the settings as the current environment', function(done) {

Code.expect(cfg.dev).to.exists();
done();
});

lab.test('should export a getCurrent function with all current environment settings',
function(done) {

Code.expect(cfg.getCurrent).to.exists();
var current = cfg.getCurrent();
Code.expect(current.env).to.equal('dev');
Code.expect(current.settings.url).to.not.exists();
Code.expect(current.settings.overwrite).to.not.exists();
Code.expect(current.settings.driver).to.equal('postgres');
Code.expect(current.settings.user).to.equal('uname');
Code.expect(current.settings.password).to.equal('pw');
Code.expect(current.settings.host).to.equal('server.com');
Code.expect(current.settings.database).to.equal('dbname');
Code.expect(current.settings.ssl).to.equal(true);

done();
});
});

lab.experiment('loading from an ENV URL within the object and overwriting it',
function() {

lab.test('should export a getCurrent function with all current environment settings',
function(done, cleanup) {

process.env.DATABASE_URL = 'postgres://uname:[email protected]/dbname';
var databaseUrl = {
'dev': {
'url': { 'ENV': 'DATABASE_URL' },
'overwrite': {
'ssl': true
}
}
};
var cfg = config.loadObject(databaseUrl, 'dev');

cleanup(function(next) {
delete process.env.DATABASE_URL;
next();
});

Code.expect(cfg.getCurrent).to.exists();
var current = cfg.getCurrent();
Code.expect(current.env).to.equal('dev');
Code.expect(current.settings.url).to.not.exists();
Code.expect(current.settings.overwrite).to.not.exists();
Code.expect(current.settings.driver).to.equal('postgres');
Code.expect(current.settings.user).to.equal('uname');
Code.expect(current.settings.password).to.equal('pw');
Code.expect(current.settings.host).to.equal('server.com');
Code.expect(current.settings.database).to.equal('dbname');
Code.expect(current.settings.ssl).to.equal(true);

done();
});
});

lab.experiment('loading from an ENV URL within the object and extending it from the ENV',
function() {

lab.test('', function(done, cleanup) {

process.env.DATABASE_URL = 'postgres://uname:[email protected]/dbname?ssl=false&testing=false';
var databaseUrl = {
'dev': {
'url': {
'ENV': 'DATABASE_URL',
},
'overwrite': {
'ssl': true,
'cache': false
},
'addIfNotExists': {
'native': true, // this on is new
'cache': true, // overwrite should have higher priority
'testing': true // already in config do not overwrite
}
}
};
var cfg = config.loadObject(databaseUrl, 'dev');

cleanup(function(next) {
delete process.env.DATABASE_URL;
next();
});

Code.expect(cfg.getCurrent).to.exists();
var current = cfg.getCurrent();
Code.expect(current.env).to.equal('dev');
Code.expect(current.settings.url).to.not.exists();
Code.expect(current.settings.overwrite).to.not.exists();
Code.expect(current.settings.addIfNotExists).to.not.exists();
Code.expect(current.settings.driver).to.equal('postgres');
Code.expect(current.settings.user).to.equal('uname');
Code.expect(current.settings.password).to.equal('pw');
Code.expect(current.settings.host).to.equal('server.com');
Code.expect(current.settings.database).to.equal('dbname');
Code.expect(current.settings.native).to.equal(true);
Code.expect(current.settings.testing).to.equal('false');
Code.expect(current.settings.cache).to.equal(false);
Code.expect(current.settings.ssl).to.equal(true);

done();
});
});
});

0 comments on commit d23c333

Please sign in to comment.