Skip to content

Commit 8be9215

Browse files
committed
feat(config): helper to overwrite and extend configuration
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 db-migrate#349 Fixes db-migrate/pg#8 Fixes db-migrate#488 Fixes db-migrate#463
1 parent b0837d5 commit 8be9215

File tree

2 files changed

+215
-8
lines changed

2 files changed

+215
-8
lines changed

lib/config.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ function walkConfig(level) {
105105
return level;
106106
}
107107

108-
exports.loadObject = function(config, currentEnv) {
108+
exports.loadObject = function(_config, currentEnv) {
109109
var out = new Config();
110+
// do not overwrite the users config
111+
var config = JSON.parse(JSON.stringify(_config));
110112

111113
for (var env in config) {
114+
115+
112116
if (config[env].ENV) {
113117
if(!process.env[config[env].ENV])
114118
log.verbose('Environment variable ' + config[env].ENV + ' is empty!');
@@ -122,6 +126,42 @@ exports.loadObject = function(config, currentEnv) {
122126
config[env] = walkConfig(config[env]);
123127
out[env] = config[env];
124128
}
129+
130+
if(typeof(config[env].url) === 'string') {
131+
132+
config[env] = Object.assign(
133+
config[env],
134+
exports.loadUrl(config[env].url, env)[env]
135+
);
136+
delete config[env].url;
137+
}
138+
else if(config[env].url && config[env].url.value) {
139+
140+
config[env].url = config[env].url.value;
141+
}
142+
143+
if(config[env].overwrite || config[env].addIfNotExists) {
144+
145+
var overwrite = config[env].overwrite || {};
146+
147+
if(config[env].addIfNotExists) {
148+
149+
var addIfNotExists = config[env].addIfNotExists;
150+
Object.keys(addIfNotExists).filter(function(key) {
151+
return !overwrite[key] && !config[env][key];
152+
}).forEach(function(key) {
153+
config[env][key] = addIfNotExists[key];
154+
});
155+
156+
delete config[env].addIfNotExists;
157+
}
158+
159+
Object.keys(overwrite).forEach(function(key) {
160+
config[env][key] = overwrite[key];
161+
});
162+
163+
delete config[env].overwrite;
164+
}
125165
}
126166

127167
if(currentEnv) {

test/config_test.js

Lines changed: 174 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var Lab = require('lab');
33
var lab = exports.lab = Lab.script();
44
var config = require('../lib/config');
55
var path = require('path');
6+
var sinon = require('sinon');
67

78
var _configLoad = config.load;
89
var _configLoadUrl = config.loadUrl;
@@ -160,18 +161,184 @@ lab.experiment('config', function() {
160161
config.load = _configLoad;
161162
config.loadUrl = _configLoadUrl;
162163

163-
lab.test('should something', function(done, cleanup) {
164-
165-
cleanup(function(next) {
166-
167-
delete require.cache[require.resolve('../lib/config')];
168-
next();
169-
});
164+
lab.test('should something', function(done) {
170165

171166
Code.expect(
172167
config.load.bind(this, configPath, 'dev')
173168
).to.not.throw;
174169
done();
175170
});
176171
});
172+
173+
lab.experiment('loading a url from url property', function() {
174+
175+
176+
lab.test('should export a valid config',
177+
function(done) {
178+
179+
var databaseUrl = {
180+
'dev': {
181+
'url': 'postgres://uname:[email protected]/dbname'
182+
}
183+
};
184+
var cfg = config.loadObject(databaseUrl, 'dev');
185+
186+
Code.expect(cfg.getCurrent).to.exists();
187+
var current = cfg.getCurrent();
188+
Code.expect(current.env).to.equal('dev');
189+
Code.expect(current.settings.url).to.not.exists();
190+
Code.expect(current.settings.driver).to.equal('postgres');
191+
Code.expect(current.settings.user).to.equal('uname');
192+
Code.expect(current.settings.password).to.equal('pw');
193+
Code.expect(current.settings.host).to.equal('server.com');
194+
Code.expect(current.settings.database).to.equal('dbname');
195+
196+
done();
197+
});
198+
199+
lab.test('should export the value if specified in suboject',
200+
function(done) {
201+
202+
var databaseUrl = {
203+
'dev': {
204+
'url': {
205+
'value': 'http://example.com'
206+
}
207+
}
208+
};
209+
var cfg = config.loadObject(databaseUrl, 'dev');
210+
211+
Code.expect(cfg.getCurrent).to.exists();
212+
var current = cfg.getCurrent();
213+
Code.expect(current.env).to.equal('dev');
214+
Code.expect(current.settings.url).to.equal('http://example.com');
215+
216+
done();
217+
});
218+
});
219+
220+
lab.experiment('loading from an URL and overwriting it', function() {
221+
222+
var databaseUrl = {
223+
'dev': {
224+
'url': 'postgres://uname:[email protected]/dbname',
225+
'overwrite': {
226+
'ssl': true
227+
}
228+
}
229+
};
230+
231+
var cfg = config.loadObject(databaseUrl, 'dev');
232+
233+
lab.test('should export the settings as the current environment', function(done) {
234+
235+
Code.expect(cfg.dev).to.exists();
236+
done();
237+
});
238+
239+
lab.test('should export a getCurrent function with all current environment settings',
240+
function(done) {
241+
242+
Code.expect(cfg.getCurrent).to.exists();
243+
var current = cfg.getCurrent();
244+
Code.expect(current.env).to.equal('dev');
245+
Code.expect(current.settings.url).to.not.exists();
246+
Code.expect(current.settings.overwrite).to.not.exists();
247+
Code.expect(current.settings.driver).to.equal('postgres');
248+
Code.expect(current.settings.user).to.equal('uname');
249+
Code.expect(current.settings.password).to.equal('pw');
250+
Code.expect(current.settings.host).to.equal('server.com');
251+
Code.expect(current.settings.database).to.equal('dbname');
252+
Code.expect(current.settings.ssl).to.equal(true);
253+
254+
done();
255+
});
256+
});
257+
258+
lab.experiment('loading from an ENV URL within the object and overwriting it',
259+
function() {
260+
261+
lab.test('should export a getCurrent function with all current environment settings',
262+
function(done, cleanup) {
263+
264+
process.env.DATABASE_URL = 'postgres://uname:[email protected]/dbname';
265+
var databaseUrl = {
266+
'dev': {
267+
'url': { 'ENV': 'DATABASE_URL' },
268+
'overwrite': {
269+
'ssl': true
270+
}
271+
}
272+
};
273+
var cfg = config.loadObject(databaseUrl, 'dev');
274+
275+
cleanup(function(next) {
276+
delete process.env.DATABASE_URL;
277+
next();
278+
});
279+
280+
Code.expect(cfg.getCurrent).to.exists();
281+
var current = cfg.getCurrent();
282+
Code.expect(current.env).to.equal('dev');
283+
Code.expect(current.settings.url).to.not.exists();
284+
Code.expect(current.settings.overwrite).to.not.exists();
285+
Code.expect(current.settings.driver).to.equal('postgres');
286+
Code.expect(current.settings.user).to.equal('uname');
287+
Code.expect(current.settings.password).to.equal('pw');
288+
Code.expect(current.settings.host).to.equal('server.com');
289+
Code.expect(current.settings.database).to.equal('dbname');
290+
Code.expect(current.settings.ssl).to.equal(true);
291+
292+
done();
293+
});
294+
});
295+
296+
lab.experiment('loading from an ENV URL within the object and extending it from the ENV',
297+
function() {
298+
299+
lab.test('', function(done, cleanup) {
300+
301+
process.env.DATABASE_URL = 'postgres://uname:[email protected]/dbname?ssl=false&testing=false';
302+
var databaseUrl = {
303+
'dev': {
304+
'url': {
305+
'ENV': 'DATABASE_URL',
306+
},
307+
'overwrite': {
308+
'ssl': true,
309+
'cache': false
310+
},
311+
'addIfNotExists': {
312+
'native': true, // this on is new
313+
'cache': true, // overwrite should have higher priority
314+
'testing': true // already in config do not overwrite
315+
}
316+
}
317+
};
318+
var cfg = config.loadObject(databaseUrl, 'dev');
319+
320+
cleanup(function(next) {
321+
delete process.env.DATABASE_URL;
322+
next();
323+
});
324+
325+
Code.expect(cfg.getCurrent).to.exists();
326+
var current = cfg.getCurrent();
327+
Code.expect(current.env).to.equal('dev');
328+
Code.expect(current.settings.url).to.not.exists();
329+
Code.expect(current.settings.overwrite).to.not.exists();
330+
Code.expect(current.settings.addIfNotExists).to.not.exists();
331+
Code.expect(current.settings.driver).to.equal('postgres');
332+
Code.expect(current.settings.user).to.equal('uname');
333+
Code.expect(current.settings.password).to.equal('pw');
334+
Code.expect(current.settings.host).to.equal('server.com');
335+
Code.expect(current.settings.database).to.equal('dbname');
336+
Code.expect(current.settings.native).to.equal(true);
337+
Code.expect(current.settings.testing).to.equal('false');
338+
Code.expect(current.settings.cache).to.equal(false);
339+
Code.expect(current.settings.ssl).to.equal(true);
340+
341+
done();
342+
});
343+
});
177344
});

0 commit comments

Comments
 (0)