Resolve ${var} values in component-config.json

App variables can now be specified in component-config.json using
the ${var} format. The value of var is looked up using app.get().

This allows loopback explorer and other loopback components which
require app variables, to be loaded declaratively using
component-config.json.
This commit is contained in:
Hage Yaapa 2015-08-28 11:49:46 +05:30
parent 8b475a97b2
commit 1b491dee85
3 changed files with 92 additions and 2 deletions

View File

@ -316,12 +316,12 @@ function setupMiddleware(app, instructions) {
} }
assert(typeof factory === 'function', assert(typeof factory === 'function',
'Middleware factory must be a function'); 'Middleware factory must be a function');
data.config = getUpdatedConfigObject(data.config, app); data.config = getUpdatedConfigObject(app, data.config);
app.middlewareFromConfig(factory, data.config); app.middlewareFromConfig(factory, data.config);
}); });
} }
function getUpdatedConfigObject(config, app) { function getUpdatedConfigObject(app, config) {
var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/; var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/;
@ -364,6 +364,7 @@ function setupComponents(app, instructions) {
instructions.components.forEach(function(data) { instructions.components.forEach(function(data) {
debug('Configuring component %j', data.sourceFile); debug('Configuring component %j', data.sourceFile);
var configFn = require(data.sourceFile); var configFn = require(data.sourceFile);
data.config = getUpdatedConfigObject(app, data.config);
configFn(app, data.config); configFn(app, data.config);
}); });
} }

View File

@ -496,6 +496,77 @@ describe('executor', function() {
}); });
describe('with component-config.json', function() {
it('should parse a simple config variable', function(done) {
boot.execute(app, simpleComponentConfig(
{ path: '${restApiRoot}' }
));
supertest(app).get('/component').end(function(err, res) {
if (err) return done(err);
expect(res.body.path).to.equal(app.get('restApiRoot'));
done();
});
});
it('should parse multiple config variables', function(done) {
boot.execute(app, simpleComponentConfig(
{ path: '${restApiRoot}', env: '${env}' }
));
supertest(app).get('/component').end(function(err, res) {
if (err) return done(err);
expect(res.body.path).to.equal(app.get('restApiRoot'));
expect(res.body.env).to.equal(app.get('env'));
done();
});
});
it('should parse config variables in an array', function(done) {
boot.execute(app, simpleComponentConfig(
{ paths: ['${restApiRoot}'] }
));
supertest(app).get('/component').end(function(err, res) {
if (err) return done(err);
expect(res.body.paths).to.eql(
[app.get('restApiRoot')]
);
done();
});
});
it('should parse config variables in an object', function(done) {
boot.execute(app, simpleComponentConfig(
{ info: { path: '${restApiRoot}' } }
));
supertest(app).get('/component').end(function(err, res) {
if (err) return done(err);
expect(res.body.info).to.eql({
path: app.get('restApiRoot')
});
done();
});
});
it('should parse config variables in a nested object', function(done) {
boot.execute(app, simpleComponentConfig(
{ nested: { info: { path: '${restApiRoot}' } } }
));
supertest(app).get('/component').end(function(err, res) {
if (err) return done(err);
expect(res.body.nested).to.eql({
info: { path: app.get('restApiRoot') }
});
done();
});
});
});
it('calls function exported by boot/init.js', function() { it('calls function exported by boot/init.js', function() {
var file = appdir.writeFileSync('boot/init.js', var file = appdir.writeFileSync('boot/init.js',
'module.exports = function(app) { app.fnCalled = true; };'); 'module.exports = function(app) { app.fnCalled = true; };');
@ -671,6 +742,17 @@ function simpleMiddlewareConfig(phase, params) {
}); });
} }
function simpleComponentConfig(config) {
return someInstructions({
components: [
{
sourceFile: path.join(__dirname, './fixtures/simple-component.js'),
config: config
}
]
});
}
function assertValidDataSource(dataSource) { function assertValidDataSource(dataSource) {
// has methods // has methods
assert.isFunc(dataSource, 'createModel'); assert.isFunc(dataSource, 'createModel');

7
test/fixtures/simple-component.js vendored Normal file
View File

@ -0,0 +1,7 @@
module.exports = function(loopbackApp, params) {
loopbackApp.use('/component', function(req, res, next) {
res.send(params);
});
};