refactor: extract runtime and registry
Move isBrowser and isServer from lib/loopback to a new file lib/runtime. Move all Model and DataSource related methods like `createModel` and `createDataSource` to lib/registry. Remove the circular dependency between lib/application and lib/loopback, by loading lib/registry and/or lib/runtime instead of lib/loopback where appropriate This commit is only moving the code around, the functionality should not be changed at all.
This commit is contained in:
parent
19425b8fd9
commit
7d674779e1
|
@ -3,6 +3,8 @@
|
|||
"content": [
|
||||
"lib/application.js",
|
||||
"lib/loopback.js",
|
||||
"lib/runtime.js",
|
||||
"lib/registry.js",
|
||||
{ "title": "Base model", "depth": 2 },
|
||||
"lib/models/model.js",
|
||||
"lib/models/data-model.js",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
var DataSource = require('loopback-datasource-juggler').DataSource
|
||||
, loopback = require('../')
|
||||
, registry = require('./registry')
|
||||
, compat = require('./compat')
|
||||
, assert = require('assert')
|
||||
, fs = require('fs')
|
||||
|
@ -128,7 +128,7 @@ app.model = function (Model, config) {
|
|||
// modeller does not understand `dataSource` option
|
||||
delete modelConfig.dataSource;
|
||||
|
||||
Model = loopback.createModelFromConfig(modelConfig);
|
||||
Model = registry.createModelFromConfig(modelConfig);
|
||||
|
||||
// delete config options already applied
|
||||
['relations', 'base', 'acls', 'hidden'].forEach(function(prop) {
|
||||
|
@ -531,7 +531,7 @@ app.boot = function(options) {
|
|||
|
||||
// try to attach models to dataSources by type
|
||||
try {
|
||||
require('./loopback').autoAttach();
|
||||
registry.autoAttach();
|
||||
} catch(e) {
|
||||
if(e.name === 'AssertionError') {
|
||||
console.warn(e);
|
||||
|
@ -594,11 +594,11 @@ function dataSourcesFromConfig(config, connectorRegistry) {
|
|||
}
|
||||
}
|
||||
|
||||
return require('./loopback').createDataSource(config);
|
||||
return registry.createDataSource(config);
|
||||
}
|
||||
|
||||
function configureModel(ModelCtor, config, app) {
|
||||
assert(ModelCtor.prototype instanceof loopback.Model,
|
||||
assert(ModelCtor.prototype instanceof registry.Model,
|
||||
'Model must be a descendant of loopback.Model');
|
||||
|
||||
var dataSource = config.dataSource;
|
||||
|
@ -614,7 +614,7 @@ function configureModel(ModelCtor, config, app) {
|
|||
config = extend({}, config);
|
||||
config.dataSource = dataSource;
|
||||
|
||||
loopback.configureModel(ModelCtor, config);
|
||||
registry.configureModel(ModelCtor, config);
|
||||
}
|
||||
|
||||
function requireDir(dir, basenames) {
|
||||
|
|
279
lib/loopback.js
279
lib/loopback.js
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
|
||||
var express = require('express')
|
||||
, proto = require('./application')
|
||||
, fs = require('fs')
|
||||
, ejs = require('ejs')
|
||||
, EventEmitter = require('events').EventEmitter
|
||||
|
@ -29,18 +30,6 @@ var express = require('express')
|
|||
|
||||
var loopback = exports = module.exports = createApplication;
|
||||
|
||||
/**
|
||||
* True if running in a browser environment; false otherwise.
|
||||
*/
|
||||
|
||||
loopback.isBrowser = typeof window !== 'undefined';
|
||||
|
||||
/**
|
||||
* True if running in a server environment; false otherwise.
|
||||
*/
|
||||
|
||||
loopback.isServer = !loopback.isBrowser;
|
||||
|
||||
/**
|
||||
* Framework version.
|
||||
*/
|
||||
|
@ -68,9 +57,6 @@ loopback.compat = require('./compat');
|
|||
function createApplication() {
|
||||
var app = express();
|
||||
|
||||
// Defer loading of `./application` until all `loopback` static methods
|
||||
// are defined, because `./application` depends on loopback.
|
||||
var proto = require('./application');
|
||||
merge(app, proto);
|
||||
|
||||
// Create a new instance of models registry per each app instance
|
||||
|
@ -93,17 +79,23 @@ function createApplication() {
|
|||
return app;
|
||||
}
|
||||
|
||||
function mixin(source) {
|
||||
for (var key in source) {
|
||||
var desc = Object.getOwnPropertyDescriptor(source, key);
|
||||
Object.defineProperty(loopback, key, desc);
|
||||
}
|
||||
}
|
||||
|
||||
mixin(require('./runtime'));
|
||||
mixin(require('./registry'));
|
||||
|
||||
/*!
|
||||
* Expose express.middleware as loopback.*
|
||||
* for example `loopback.errorHandler` etc.
|
||||
*/
|
||||
|
||||
for (var key in express) {
|
||||
Object.defineProperty(
|
||||
loopback
|
||||
, key
|
||||
, Object.getOwnPropertyDescriptor(express, key));
|
||||
}
|
||||
mixin(express);
|
||||
|
||||
|
||||
/*!
|
||||
* Expose additional loopback middleware
|
||||
|
@ -129,143 +121,6 @@ if (loopback.isServer) {
|
|||
|
||||
loopback.errorHandler.title = 'Loopback';
|
||||
|
||||
/**
|
||||
* Create a data source with passing the provided options to the connector.
|
||||
*
|
||||
* @param {String} name Optional name.
|
||||
* @options {Object} Data Source options
|
||||
* @property {Object} connector LoopBack connector.
|
||||
* @property {*} Other properties See the relevant connector documentation.
|
||||
*/
|
||||
|
||||
loopback.createDataSource = function (name, options) {
|
||||
var ds = new DataSource(name, options, loopback.Model.modelBuilder);
|
||||
ds.createModel = function (name, properties, settings) {
|
||||
var ModelCtor = loopback.createModel(name, properties, settings);
|
||||
ModelCtor.attachTo(ds);
|
||||
return ModelCtor;
|
||||
};
|
||||
|
||||
if(ds.settings && ds.settings.defaultForType) {
|
||||
loopback.setDefaultDataSourceForType(ds.settings.defaultForType, ds);
|
||||
}
|
||||
|
||||
return ds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a named vanilla JavaScript class constructor with an attached set of properties and options.
|
||||
*
|
||||
* @param {String} name Unique name.
|
||||
* @param {Object} properties
|
||||
* @param {Object} options (optional)
|
||||
*/
|
||||
|
||||
loopback.createModel = function (name, properties, options) {
|
||||
options = options || {};
|
||||
var BaseModel = options.base || options.super;
|
||||
|
||||
if(typeof BaseModel === 'string') {
|
||||
BaseModel = loopback.getModel(BaseModel);
|
||||
}
|
||||
|
||||
BaseModel = BaseModel || loopback.Model;
|
||||
|
||||
var model = BaseModel.extend(name, properties, options);
|
||||
|
||||
// try to attach
|
||||
try {
|
||||
loopback.autoAttachModel(model);
|
||||
} catch(e) {}
|
||||
|
||||
return model;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a model as described by the configuration object.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```js
|
||||
* loopback.createModelFromConfig({
|
||||
* name: 'Author',
|
||||
* properties: {
|
||||
* firstName: 'string',
|
||||
* lastName: 'string
|
||||
* },
|
||||
* relations: {
|
||||
* books: {
|
||||
* model: 'Book',
|
||||
* type: 'hasAndBelongsToMany'
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @options {Object} model configuration
|
||||
* @property {String} name Unique name.
|
||||
* @property {Object=} properties Model properties
|
||||
* @property {Object=} options Model options. Options can be specified on the
|
||||
* top level config object too. E.g. `{ base: 'User' }` is the same as
|
||||
* `{ options: { base: 'User' } }`.
|
||||
*/
|
||||
loopback.createModelFromConfig = function(config) {
|
||||
var name = config.name;
|
||||
var properties = config.properties;
|
||||
var options = buildModelOptionsFromConfig(config);
|
||||
|
||||
assert(typeof name === 'string',
|
||||
'The model-config property `name` must be a string');
|
||||
|
||||
return loopback.createModel(name, properties, options);
|
||||
};
|
||||
|
||||
function buildModelOptionsFromConfig(config) {
|
||||
var options = merge({}, config.options);
|
||||
for (var key in config) {
|
||||
if (['name', 'properties', 'options'].indexOf(key) !== -1) {
|
||||
// Skip items which have special meaning
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options[key] !== undefined) {
|
||||
// When both `config.key` and `config.options.key` are set,
|
||||
// use the latter one
|
||||
continue;
|
||||
}
|
||||
|
||||
options[key] = config[key];
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter an existing Model class.
|
||||
* @param {Model} ModelCtor The model constructor to alter.
|
||||
* @options {Object} Additional configuration to apply
|
||||
* @property {DataSource} dataSource Attach the model to a dataSource.
|
||||
* @property {Object} relations Model relations to add/update.
|
||||
*/
|
||||
loopback.configureModel = function(ModelCtor, config) {
|
||||
var settings = ModelCtor.settings;
|
||||
|
||||
if (config.relations) {
|
||||
var relations = settings.relations = settings.relations || {};
|
||||
Object.keys(config.relations).forEach(function(key) {
|
||||
relations[key] = merge(relations[key] || {}, config.relations[key]);
|
||||
});
|
||||
}
|
||||
|
||||
// It's important to attach the datasource after we have updated
|
||||
// configuration, so that the datasource picks up updated relations
|
||||
if (config.dataSource) {
|
||||
assert(config.dataSource instanceof DataSource,
|
||||
'Cannot configure ' + ModelCtor.modelName +
|
||||
': config.dataSource must be an instance of loopback.DataSource');
|
||||
ModelCtor.attachTo(config.dataSource);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a remote method to a model.
|
||||
* @param {Function} fn
|
||||
|
@ -298,119 +153,11 @@ loopback.template = function (file) {
|
|||
return ejs.compile(str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an in-memory data source. Use one if it already exists.
|
||||
*
|
||||
* @param {String} [name] The name of the data source. If not provided, the `'default'` is used.
|
||||
*/
|
||||
|
||||
loopback.memory = function (name) {
|
||||
name = name || 'default';
|
||||
var memory = (
|
||||
this._memoryDataSources
|
||||
|| (this._memoryDataSources = {})
|
||||
)[name];
|
||||
|
||||
if(!memory) {
|
||||
memory = this._memoryDataSources[name] = loopback.createDataSource({
|
||||
connector: loopback.Memory
|
||||
});
|
||||
}
|
||||
|
||||
return memory;
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up a model class by name from all models created by loopback.createModel()
|
||||
* @param {String} modelName The model name
|
||||
* @returns {Model} The model class
|
||||
*/
|
||||
loopback.getModel = function(modelName) {
|
||||
return loopback.Model.modelBuilder.models[modelName];
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up a model class by the base model class. The method can be used by LoopBack
|
||||
* to find configured models in models.json over the base model.
|
||||
* @param {Model} The base model class
|
||||
* @returns {Model} The subclass if found or the base class
|
||||
*/
|
||||
loopback.getModelByType = function(modelType) {
|
||||
assert(typeof modelType === 'function', 'The model type must be a constructor');
|
||||
var models = loopback.Model.modelBuilder.models;
|
||||
for(var m in models) {
|
||||
if(models[m].prototype instanceof modelType) {
|
||||
return models[m];
|
||||
}
|
||||
}
|
||||
return modelType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default `dataSource` for a given `type`.
|
||||
* @param {String} type The datasource type
|
||||
* @param {Object|DataSource} dataSource The data source settings or instance
|
||||
* @returns {DataSource} The data source instance
|
||||
*/
|
||||
|
||||
loopback.setDefaultDataSourceForType = function(type, dataSource) {
|
||||
var defaultDataSources = this.defaultDataSources || (this.defaultDataSources = {});
|
||||
|
||||
if(!(dataSource instanceof DataSource)) {
|
||||
dataSource = this.createDataSource(dataSource);
|
||||
}
|
||||
|
||||
defaultDataSources[type] = dataSource;
|
||||
return dataSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the default `dataSource` for a given `type`.
|
||||
* @param {String} type The datasource type
|
||||
* @returns {DataSource} The data source instance
|
||||
*/
|
||||
|
||||
loopback.getDefaultDataSourceForType = function(type) {
|
||||
return this.defaultDataSources && this.defaultDataSources[type];
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach any model that does not have a dataSource to
|
||||
* the default dataSource for the type the Model requests
|
||||
*/
|
||||
|
||||
loopback.autoAttach = function() {
|
||||
var models = this.Model.modelBuilder.models;
|
||||
assert.equal(typeof models, 'object', 'Cannot autoAttach without a models object');
|
||||
|
||||
Object.keys(models).forEach(function(modelName) {
|
||||
var ModelCtor = models[modelName];
|
||||
|
||||
// Only auto attach if the model doesn't have an explicit data source
|
||||
if(ModelCtor && (!(ModelCtor.dataSource instanceof DataSource))) {
|
||||
loopback.autoAttachModel(ModelCtor);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
loopback.autoAttachModel = function(ModelCtor) {
|
||||
if(ModelCtor.autoAttach) {
|
||||
var ds = loopback.getDefaultDataSourceForType(ModelCtor.autoAttach);
|
||||
|
||||
assert(ds instanceof DataSource, 'cannot autoAttach model "'
|
||||
+ ModelCtor.modelName
|
||||
+ '". No dataSource found of type ' + ModelCtor.autoAttach);
|
||||
|
||||
ModelCtor.attachTo(ds);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Built in models / services
|
||||
*/
|
||||
|
||||
loopback.Model = require('./models/model');
|
||||
loopback.DataModel = require('./models/data-model');
|
||||
loopback.Email = require('./models/email');
|
||||
loopback.User = require('./models/user');
|
||||
loopback.Application = require('./models/application');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*!
|
||||
* Module Dependencies.
|
||||
*/
|
||||
var loopback = require('../loopback');
|
||||
var registry = require('../registry');
|
||||
var compat = require('../compat');
|
||||
var ModelBuilder = require('loopback-datasource-juggler').ModelBuilder;
|
||||
var modeler = new ModelBuilder();
|
||||
|
@ -128,7 +128,7 @@ Model._ACL = function getACL(ACL) {
|
|||
return _aclModel;
|
||||
}
|
||||
var aclModel = require('./acl').ACL;
|
||||
_aclModel = loopback.getModelByType(aclModel);
|
||||
_aclModel = registry.getModelByType(aclModel);
|
||||
return _aclModel;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* This file exports methods and objects for manipulating
|
||||
* Models and DataSources.
|
||||
*
|
||||
* It is an internal file that should not be used outside of loopback.
|
||||
* All exported entities can be accessed via the `loopback` object.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var extend = require('util')._extend;
|
||||
var DataSource = require('loopback-datasource-juggler').DataSource;
|
||||
|
||||
var registry = module.exports;
|
||||
|
||||
|
||||
/**
|
||||
* Create a named vanilla JavaScript class constructor with an attached
|
||||
* set of properties and options.
|
||||
*
|
||||
* @param {String} name Unique name.
|
||||
* @param {Object} properties
|
||||
* @param {Object} options (optional)
|
||||
*
|
||||
* @header loopback.createModel
|
||||
*/
|
||||
|
||||
registry.createModel = function (name, properties, options) {
|
||||
options = options || {};
|
||||
var BaseModel = options.base || options.super;
|
||||
|
||||
if(typeof BaseModel === 'string') {
|
||||
var baseName = BaseModel;
|
||||
BaseModel = this.getModel(BaseModel);
|
||||
|
||||
if (BaseModel === undefined) {
|
||||
if (baseName === 'DataModel') {
|
||||
console.warn('Model `%s` is extending deprecated `DataModel. ' +
|
||||
'Use `PeristedModel` instead.', name);
|
||||
BaseModel = this.PersistedModel;
|
||||
} else {
|
||||
console.warn('Model `%s` is extending an unknown model `%s`. ' +
|
||||
'Using `PersistedModel` as the base.', name, baseName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseModel = BaseModel || this.Model;
|
||||
|
||||
var model = BaseModel.extend(name, properties, options);
|
||||
|
||||
// try to attach
|
||||
try {
|
||||
this.autoAttachModel(model);
|
||||
} catch(e) {}
|
||||
|
||||
return model;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a model as described by the configuration object.
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
* ```js
|
||||
* loopback.createModelFromConfig({
|
||||
* name: 'Author',
|
||||
* properties: {
|
||||
* firstName: 'string',
|
||||
* lastName: 'string
|
||||
* },
|
||||
* relations: {
|
||||
* books: {
|
||||
* model: 'Book',
|
||||
* type: 'hasAndBelongsToMany'
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @options {Object} model configuration
|
||||
* @property {String} name Unique name.
|
||||
* @property {Object} [properties] Model properties
|
||||
* @property {Object} [options] Model options. Options can be specified on the
|
||||
* top level config object too. E.g. `{ base: 'User' }` is the same as
|
||||
* `{ options: { base: 'User' } }`.
|
||||
*
|
||||
* @header loopback.createModelFromConfig(config)
|
||||
*/
|
||||
|
||||
registry.createModelFromConfig = function(config) {
|
||||
var name = config.name;
|
||||
var properties = config.properties;
|
||||
var options = buildModelOptionsFromConfig(config);
|
||||
|
||||
assert(typeof name === 'string',
|
||||
'The model-config property `name` must be a string');
|
||||
|
||||
return this.createModel(name, properties, options);
|
||||
};
|
||||
|
||||
function buildModelOptionsFromConfig(config) {
|
||||
var options = extend({}, config.options);
|
||||
for (var key in config) {
|
||||
if (['name', 'properties', 'options'].indexOf(key) !== -1) {
|
||||
// Skip items which have special meaning
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options[key] !== undefined) {
|
||||
// When both `config.key` and `config.options.key` are set,
|
||||
// use the latter one
|
||||
continue;
|
||||
}
|
||||
|
||||
options[key] = config[key];
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter an existing Model class.
|
||||
* @param {Model} ModelCtor The model constructor to alter.
|
||||
* @options {Object} Additional configuration to apply
|
||||
* @property {DataSource} dataSource Attach the model to a dataSource.
|
||||
* @property {Object} [relations] Model relations to add/update.
|
||||
*
|
||||
* @header loopback.configureModel(ModelCtor, config)
|
||||
*/
|
||||
|
||||
registry.configureModel = function(ModelCtor, config) {
|
||||
var settings = ModelCtor.settings;
|
||||
|
||||
if (config.relations) {
|
||||
var relations = settings.relations = settings.relations || {};
|
||||
Object.keys(config.relations).forEach(function(key) {
|
||||
relations[key] = extend(relations[key] || {}, config.relations[key]);
|
||||
});
|
||||
}
|
||||
|
||||
// It's important to attach the datasource after we have updated
|
||||
// configuration, so that the datasource picks up updated relations
|
||||
if (config.dataSource) {
|
||||
assert(config.dataSource instanceof DataSource,
|
||||
'Cannot configure ' + ModelCtor.modelName +
|
||||
': config.dataSource must be an instance of DataSource');
|
||||
ModelCtor.attachTo(config.dataSource);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up a model class by name from all models created by
|
||||
* `loopback.createModel()`
|
||||
* @param {String} modelName The model name
|
||||
* @returns {Model} The model class
|
||||
*
|
||||
* @header loopback.getModel(modelName)
|
||||
*/
|
||||
registry.getModel = function(modelName) {
|
||||
return this.Model.modelBuilder.models[modelName];
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up a model class by the base model class.
|
||||
* The method can be used by LoopBack
|
||||
* to find configured models in models.json over the base model.
|
||||
* @param {Model} modelType The base model class
|
||||
* @returns {Model} The subclass if found or the base class
|
||||
*
|
||||
* @header loopback.getModelByType(modelType)
|
||||
*/
|
||||
registry.getModelByType = function(modelType) {
|
||||
assert(typeof modelType === 'function',
|
||||
'The model type must be a constructor');
|
||||
var models = this.Model.modelBuilder.models;
|
||||
for(var m in models) {
|
||||
if(models[m].prototype instanceof modelType) {
|
||||
return models[m];
|
||||
}
|
||||
}
|
||||
return modelType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a data source with passing the provided options to the connector.
|
||||
*
|
||||
* @param {String} name Optional name.
|
||||
* @options {Object} Data Source options
|
||||
* @property {Object} connector LoopBack connector.
|
||||
* @property {*} Other properties See the relevant connector documentation.
|
||||
*
|
||||
* @header loopback.createDataSource(name, options)
|
||||
*/
|
||||
|
||||
registry.createDataSource = function (name, options) {
|
||||
var loopback = this;
|
||||
var ds = new DataSource(name, options, loopback.Model.modelBuilder);
|
||||
ds.createModel = function (name, properties, settings) {
|
||||
var ModelCtor = loopback.createModel(name, properties, settings);
|
||||
ModelCtor.attachTo(ds);
|
||||
return ModelCtor;
|
||||
};
|
||||
|
||||
if(ds.settings && ds.settings.defaultForType) {
|
||||
this.setDefaultDataSourceForType(ds.settings.defaultForType, ds);
|
||||
}
|
||||
|
||||
return ds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an in-memory data source. Use one if it already exists.
|
||||
*
|
||||
* @param {String} [name] The name of the data source.
|
||||
* If not provided, the `'default'` is used.
|
||||
*
|
||||
* @header loopback.memory()
|
||||
*/
|
||||
|
||||
registry.memory = function (name) {
|
||||
name = name || 'default';
|
||||
var memory = (
|
||||
this._memoryDataSources || (this._memoryDataSources = {})
|
||||
)[name];
|
||||
|
||||
if(!memory) {
|
||||
memory = this._memoryDataSources[name] = this.createDataSource({
|
||||
connector: loopback.Memory
|
||||
});
|
||||
}
|
||||
|
||||
return memory;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default `dataSource` for a given `type`.
|
||||
* @param {String} type The datasource type
|
||||
* @param {Object|DataSource} dataSource The data source settings or instance
|
||||
* @returns {DataSource} The data source instance
|
||||
*
|
||||
* @header loopback.setDefaultDataSourceForType(type, dataSource)
|
||||
*/
|
||||
|
||||
registry.setDefaultDataSourceForType = function(type, dataSource) {
|
||||
var defaultDataSources = this.defaultDataSources ||
|
||||
(this.defaultDataSources = {});
|
||||
|
||||
if(!(dataSource instanceof DataSource)) {
|
||||
dataSource = this.createDataSource(dataSource);
|
||||
}
|
||||
|
||||
defaultDataSources[type] = dataSource;
|
||||
return dataSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the default `dataSource` for a given `type`.
|
||||
* @param {String} type The datasource type
|
||||
* @returns {DataSource} The data source instance
|
||||
* @header loopback.getDefaultDataSourceForType()
|
||||
*/
|
||||
|
||||
registry.getDefaultDataSourceForType = function(type) {
|
||||
return this.defaultDataSources && this.defaultDataSources[type];
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach any model that does not have a dataSource to
|
||||
* the default dataSource for the type the Model requests
|
||||
* @header loopback.autoAttach()
|
||||
*/
|
||||
|
||||
registry.autoAttach = function() {
|
||||
var models = this.Model.modelBuilder.models;
|
||||
assert.equal(typeof models, 'object', 'Cannot autoAttach without a models object');
|
||||
|
||||
Object.keys(models).forEach(function(modelName) {
|
||||
var ModelCtor = models[modelName];
|
||||
|
||||
// Only auto attach if the model doesn't have an explicit data source
|
||||
if(ModelCtor && (!(ModelCtor.dataSource instanceof DataSource))) {
|
||||
this.autoAttachModel(ModelCtor);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
registry.autoAttachModel = function(ModelCtor) {
|
||||
if(ModelCtor.autoAttach) {
|
||||
var ds = this.getDefaultDataSourceForType(ModelCtor.autoAttach);
|
||||
|
||||
assert(ds instanceof DataSource, 'cannot autoAttach model "'
|
||||
+ ModelCtor.modelName
|
||||
+ '". No dataSource found of type ' + ModelCtor.autoAttach);
|
||||
|
||||
ModelCtor.attachTo(ds);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Core models
|
||||
* @private
|
||||
*/
|
||||
|
||||
registry.Model = require('./models/model');
|
||||
registry.DataModel = require('./models/data-model');
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* This is an internal file that should not be used outside of loopback.
|
||||
* All exported entities can be accessed via the `loopback` object.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var runtime = exports;
|
||||
|
||||
/**
|
||||
* True if running in a browser environment; false otherwise.
|
||||
* @header loopback.isBrowser
|
||||
*/
|
||||
|
||||
runtime.isBrowser = typeof window !== 'undefined';
|
||||
|
||||
/**
|
||||
* True if running in a server environment; false otherwise.
|
||||
* @header loopback.isServer
|
||||
*/
|
||||
|
||||
runtime.isServer = !runtime.isBrowser;
|
||||
|
Loading…
Reference in New Issue