Merge pull request #149 from hacksparrow/feature/declarative-loopback-rest

Resolve ${var} values in middleware.json
This commit is contained in:
Miroslav Bajtoš 2015-08-25 15:32:42 +02:00
commit 0b0f0ed202
3 changed files with 134 additions and 1 deletions

View File

@ -316,10 +316,50 @@ 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);
app.middlewareFromConfig(factory, data.config); app.middlewareFromConfig(factory, data.config);
}); });
} }
function getUpdatedConfigObject(config, app) {
var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/;
function getConfigVariable(param) {
var configVariable = param;
var match = configVariable.match(DYNAMIC_CONFIG_PARAM);
if (match) {
var appValue = app.get(match[1]);
if (appValue !== undefined) {
configVariable = appValue;
} else {
console.warn('%s does not resolve to a valid value. ' +
'"%s" must be resolvable by app.get().', param, match[1]);
}
}
return configVariable;
}
function interpolateVariables(config) {
var interpolated = {};
Object.keys(config).forEach(function(configKey) {
var value = config[configKey];
if (Array.isArray(value)) {
interpolated[configKey] = value.map(getConfigVariable);
} else if (typeof value === 'string') {
interpolated[configKey] = getConfigVariable(value);
} else if (typeof value === 'object' && Object.keys(value).length) {
interpolated[configKey] = interpolateVariables(value);
} else {
interpolated[configKey] = value;
}
});
return interpolated;
}
return interpolateVariables(config);
}
function setupComponents(app, instructions) { 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);

View File

@ -292,7 +292,7 @@ describe('executor', function() {
}); });
}); });
describe ('for mixins', function() { describe('for mixins', function() {
var options; var options;
beforeEach(function() { beforeEach(function() {
appdir.writeFileSync('custom-mixins/example.js', appdir.writeFileSync('custom-mixins/example.js',
@ -425,6 +425,77 @@ describe('executor', function() {
}); });
}); });
describe('with middleware.json', function() {
it('should parse a simple config variable', function(done) {
boot.execute(app, simpleMiddlewareConfig('routes',
{ path: '${restApiRoot}' }
));
supertest(app).get('/').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, simpleMiddlewareConfig('routes',
{ path: '${restApiRoot}', env: '${env}' }
));
supertest(app).get('/').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, simpleMiddlewareConfig('routes',
{ paths: ['${restApiRoot}'] }
));
supertest(app).get('/').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, simpleMiddlewareConfig('routes',
{ info: { path: '${restApiRoot}' } }
));
supertest(app).get('/').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, simpleMiddlewareConfig('routes',
{ nested: { info: { path: '${restApiRoot}' } } }
));
supertest(app).get('/').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; };');
@ -583,6 +654,23 @@ describe('executor', function() {
}); });
}); });
function simpleMiddlewareConfig(phase, params) {
return someInstructions({
middleware: {
phases: [phase],
middleware: [
{
sourceFile: path.join(__dirname, './fixtures/simple-middleware.js'),
config: {
phase: phase,
params: params
}
}
]
}
});
}
function assertValidDataSource(dataSource) { function assertValidDataSource(dataSource) {
// has methods // has methods
assert.isFunc(dataSource, 'createModel'); assert.isFunc(dataSource, 'createModel');

5
test/fixtures/simple-middleware.js vendored Normal file
View File

@ -0,0 +1,5 @@
module.exports = function(params) {
return function(req, res, next) {
res.send(params);
};
};