Custom rootDir for models and datasources

Support custom project layouts where model & datasource config files
are located in a different place from the app config.

Example:

    # API server
    server/app.config.json
    server/datasources.json

    # shared between server & client
    models.json
    models/

    # isomorphic client
    client/app.config.json
    client/datasources.json
This commit is contained in:
Miroslav Bajtoš 2014-05-27 14:46:20 +02:00
parent c1743dc2ff
commit 2a619773d4
3 changed files with 62 additions and 4 deletions

View File

@ -1,2 +1,3 @@
node_modules/
coverage/
test/sandbox/

View File

@ -99,6 +99,10 @@ var ConfigLoader = require('./lib/config-loader');
* @property {Object} models Object containing `Model` definitions (optional).
* @property {Object} dataSources Object containing `DataSource`
* definitions (optional).
* @property {String} modelsRootDir Directory to use when loading `models.json`
* and `models/*.js`. Defaults to `appRootDir`.
* @property {String} datasourcesRootDir Directory to use when loading
* `datasources.json`. Defaults to `appRootDir`.
* @end
*
* @header boot(app, [options])
@ -115,9 +119,14 @@ exports = module.exports = function bootLoopBackApp(app, options) {
var env = app.get('env');
var appConfig = options.app || ConfigLoader.loadAppConfig(appRootDir, env);
var modelConfig = options.models || ConfigLoader.loadModels(appRootDir, env);
var modelsRootDir = options.modelsRootDir || appRootDir;
var modelConfig = options.models ||
ConfigLoader.loadModels(modelsRootDir, env);
var dsRootDir = options.dsRootDir || appRootDir;
var dataSourceConfig = options.dataSources ||
ConfigLoader.loadDataSources(appRootDir, env);
ConfigLoader.loadDataSources(dsRootDir, env);
assertIsValidConfig('app', appConfig);
assertIsValidConfig('model', modelConfig);
@ -204,7 +213,7 @@ exports = module.exports = function bootLoopBackApp(app, options) {
}
// require directories
requireDir(path.join(appRootDir, 'models'));
requireDir(path.join(modelsRootDir, 'models'));
requireDir(path.join(appRootDir, 'boot'));
};

View File

@ -300,6 +300,48 @@ describe('bootLoopBackApp', function() {
expect(app.settings).to.have.property('fromJs', true);
});
it('supports `dsRootDir` option', function() {
givenAppInSandbox();
var customDir = path.resolve(appDir, 'custom');
fs.mkdirsSync(customDir);
fs.renameSync(
path.resolve(appDir, 'datasources.json'),
path.resolve(customDir, 'datasources.json'));
var app = loopback();
// workaround for https://github.com/strongloop/loopback/pull/283
app.datasources = app.dataSources = {};
boot(app, {
appRootDir: appDir,
dsRootDir: path.resolve(appDir, 'custom')
});
expect(app.datasources).to.have.property('db');
});
it('supports `modelsRootDir` option', function() {
givenAppInSandbox();
writeAppConfigFile('custom/models.json', {
foo: { dataSource: 'db' }
});
global.testData = {};
writeAppFile('custom/models/foo.js', 'global.testData.foo = "loaded";');
var app = loopback();
boot(app, {
appRootDir: appDir,
modelsRootDir: path.resolve(appDir, 'custom')
});
expect(app.models).to.have.property('foo');
expect(global.testData).to.have.property('foo', 'loaded');
});
});
});
@ -342,5 +384,11 @@ function givenAppInSandbox(appConfig, dataSources, models) {
}
function writeAppConfigFile(name, json) {
fs.writeJsonFileSync(path.resolve(appDir, name), json);
writeAppFile(name, JSON.stringify(json, null, 2));
}
function writeAppFile(name, content) {
var filePath = path.resolve(appDir, name);
fs.mkdirsSync(path.dirname(filePath));
fs.writeFileSync(filePath, content, 'utf-8');
}