2014-01-17 18:40:41 +00:00
|
|
|
/*!
|
2013-07-16 18:05:38 +00:00
|
|
|
* Module dependencies.
|
|
|
|
*/
|
|
|
|
|
|
|
|
var express = require('express')
|
2014-06-06 09:47:25 +00:00
|
|
|
, proto = require('./application')
|
2013-07-16 18:05:38 +00:00
|
|
|
, fs = require('fs')
|
|
|
|
, ejs = require('ejs')
|
|
|
|
, EventEmitter = require('events').EventEmitter
|
|
|
|
, path = require('path')
|
2013-07-30 21:26:49 +00:00
|
|
|
, DataSource = require('loopback-datasource-juggler').DataSource
|
|
|
|
, ModelBuilder = require('loopback-datasource-juggler').ModelBuilder
|
2014-02-12 00:01:51 +00:00
|
|
|
, i8n = require('inflection')
|
2014-02-19 22:11:16 +00:00
|
|
|
, merge = require('util')._extend
|
2014-02-14 18:31:30 +00:00
|
|
|
, assert = require('assert');
|
2013-07-16 18:05:38 +00:00
|
|
|
|
|
|
|
/**
|
2014-04-02 22:46:39 +00:00
|
|
|
* Main entry for LoopBack core module. It provides static properties and
|
2014-01-17 18:40:41 +00:00
|
|
|
* methods to create models and data sources. The module itself is a function
|
|
|
|
* that creates loopback `app`. For example,
|
|
|
|
*
|
|
|
|
* ```js
|
|
|
|
* var loopback = require('loopback');
|
|
|
|
* var app = loopback();
|
|
|
|
* ```
|
2014-04-02 22:46:39 +00:00
|
|
|
*
|
|
|
|
* @class loopback
|
|
|
|
* @header loopback
|
2013-07-16 18:05:38 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
var loopback = exports = module.exports = createApplication;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Framework version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
loopback.version = require('../package.json').version;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Expose mime.
|
|
|
|
*/
|
|
|
|
|
|
|
|
loopback.mime = express.mime;
|
|
|
|
|
2014-01-22 10:22:23 +00:00
|
|
|
/*!
|
|
|
|
* Compatibility layer, intentionally left undocumented.
|
|
|
|
*/
|
|
|
|
loopback.compat = require('./compat');
|
|
|
|
|
2014-03-11 01:05:44 +00:00
|
|
|
/*!
|
2013-07-16 18:05:38 +00:00
|
|
|
* Create an loopback application.
|
|
|
|
*
|
|
|
|
* @return {Function}
|
|
|
|
* @api public
|
|
|
|
*/
|
|
|
|
|
|
|
|
function createApplication() {
|
|
|
|
var app = express();
|
|
|
|
|
2014-02-12 00:01:51 +00:00
|
|
|
merge(app, proto);
|
2013-07-16 18:05:38 +00:00
|
|
|
|
2014-02-04 19:28:19 +00:00
|
|
|
// Create a new instance of models registry per each app instance
|
|
|
|
app.models = function() {
|
|
|
|
return proto.models.apply(this, arguments);
|
|
|
|
};
|
|
|
|
|
2014-05-27 12:33:42 +00:00
|
|
|
// Create a new instance of datasources registry per each app instance
|
|
|
|
app.datasources = app.dataSources = {};
|
|
|
|
|
2014-05-28 13:02:55 +00:00
|
|
|
// Create a new instance of connector registry per each app instance
|
|
|
|
app.connectors = {};
|
|
|
|
|
|
|
|
// Register built-in connectors. It's important to keep this code
|
|
|
|
// hand-written, so that all require() calls are static
|
|
|
|
// and thus browserify can process them (include connectors in the bundle)
|
|
|
|
app.connector('memory', loopback.Memory);
|
|
|
|
app.connector('remote', loopback.Remote);
|
|
|
|
|
2013-07-16 18:05:38 +00:00
|
|
|
return app;
|
|
|
|
}
|
|
|
|
|
2014-06-06 09:47:25 +00:00
|
|
|
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'));
|
|
|
|
|
2014-01-17 18:40:41 +00:00
|
|
|
/*!
|
2013-07-16 18:05:38 +00:00
|
|
|
* Expose express.middleware as loopback.*
|
|
|
|
* for example `loopback.errorHandler` etc.
|
|
|
|
*/
|
|
|
|
|
2014-06-06 09:47:25 +00:00
|
|
|
mixin(express);
|
|
|
|
|
2013-07-16 18:05:38 +00:00
|
|
|
|
2014-01-17 18:40:41 +00:00
|
|
|
/*!
|
2013-07-16 18:05:38 +00:00
|
|
|
* Expose additional loopback middleware
|
|
|
|
* for example `loopback.configure` etc.
|
2014-02-12 00:01:51 +00:00
|
|
|
*
|
|
|
|
* ***only in node***
|
2013-07-16 18:05:38 +00:00
|
|
|
*/
|
|
|
|
|
2014-02-12 00:01:51 +00:00
|
|
|
if (loopback.isServer) {
|
|
|
|
fs
|
|
|
|
.readdirSync(path.join(__dirname, 'middleware'))
|
|
|
|
.filter(function (file) {
|
|
|
|
return file.match(/\.js$/);
|
|
|
|
})
|
|
|
|
.forEach(function (m) {
|
|
|
|
loopback[m.replace(/\.js$/, '')] = require('./middleware/' + m);
|
|
|
|
});
|
|
|
|
}
|
2013-07-16 18:05:38 +00:00
|
|
|
|
2014-01-17 18:40:41 +00:00
|
|
|
/*!
|
2013-07-16 18:05:38 +00:00
|
|
|
* Error handler title
|
|
|
|
*/
|
|
|
|
|
|
|
|
loopback.errorHandler.title = 'Loopback';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a remote method to a model.
|
|
|
|
* @param {Function} fn
|
|
|
|
* @param {Object} options (optional)
|
|
|
|
*/
|
|
|
|
|
|
|
|
loopback.remoteMethod = function (fn, options) {
|
|
|
|
fn.shared = true;
|
|
|
|
if(typeof options === 'object') {
|
|
|
|
Object.keys(options).forEach(function (key) {
|
|
|
|
fn[key] = options[key];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
fn.http = fn.http || {verb: 'get'};
|
2014-02-14 18:31:30 +00:00
|
|
|
};
|
2013-07-16 18:05:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a template helper.
|
|
|
|
*
|
|
|
|
* var render = loopback.template('foo.ejs');
|
|
|
|
* var html = render({foo: 'bar'});
|
|
|
|
*
|
|
|
|
* @param {String} path Path to the template file.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
|
|
|
|
loopback.template = function (file) {
|
|
|
|
var templates = this._templates || (this._templates = {});
|
|
|
|
var str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8'));
|
|
|
|
return ejs.compile(str);
|
2014-02-14 18:31:30 +00:00
|
|
|
};
|
2013-07-16 18:05:38 +00:00
|
|
|
|
2013-11-19 20:23:02 +00:00
|
|
|
|
2014-03-11 01:05:44 +00:00
|
|
|
/*!
|
2013-07-16 18:05:38 +00:00
|
|
|
* Built in models / services
|
|
|
|
*/
|
|
|
|
|
|
|
|
loopback.Email = require('./models/email');
|
|
|
|
loopback.User = require('./models/user');
|
2013-10-11 20:44:10 +00:00
|
|
|
loopback.Application = require('./models/application');
|
2013-11-13 19:49:08 +00:00
|
|
|
loopback.AccessToken = require('./models/access-token');
|
2013-11-19 19:02:43 +00:00
|
|
|
loopback.Role = require('./models/role').Role;
|
|
|
|
loopback.RoleMapping = require('./models/role').RoleMapping;
|
2013-11-19 00:13:40 +00:00
|
|
|
loopback.ACL = require('./models/acl').ACL;
|
|
|
|
loopback.Scope = require('./models/acl').Scope;
|
|
|
|
|
2014-01-17 18:40:41 +00:00
|
|
|
/*!
|
2013-11-19 00:13:40 +00:00
|
|
|
* Automatically attach these models to dataSources
|
|
|
|
*/
|
|
|
|
|
|
|
|
var dataSourceTypes = {
|
|
|
|
DB: 'db',
|
|
|
|
MAIL: 'mail'
|
|
|
|
};
|
|
|
|
|
|
|
|
loopback.Email.autoAttach = dataSourceTypes.MAIL;
|
2014-02-20 01:09:36 +00:00
|
|
|
loopback.DataModel.autoAttach = dataSourceTypes.DB;
|
2013-11-19 00:13:40 +00:00
|
|
|
loopback.User.autoAttach = dataSourceTypes.DB;
|
|
|
|
loopback.AccessToken.autoAttach = dataSourceTypes.DB;
|
|
|
|
loopback.Role.autoAttach = dataSourceTypes.DB;
|
2013-11-19 19:02:43 +00:00
|
|
|
loopback.RoleMapping.autoAttach = dataSourceTypes.DB;
|
2013-11-19 00:13:40 +00:00
|
|
|
loopback.ACL.autoAttach = dataSourceTypes.DB;
|
|
|
|
loopback.Scope.autoAttach = dataSourceTypes.DB;
|
|
|
|
loopback.Application.autoAttach = dataSourceTypes.DB;
|