Skip to content

Commit

Permalink
Merge branch 'release/2.0.1' into production
Browse files Browse the repository at this point in the history
  • Loading branch information
Raymond Feng committed Jul 26, 2014
2 parents a3720bc + 0297ba3 commit 0e3187c
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 66 deletions.
106 changes: 54 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,79 @@
LoopBack is a highly extensible, open source Node.js framework that enables you to:
LoopBack is a highly-extensible, open-source Node.js framework that enables you to:

* Create dynamic end-to-end REST APIs with little or no coding
* Easily access data from Oracle, MySQL, PostgreSQL, MS SQL Server, MongoDB, SOAP and other REST APIs
* Incorporate model relationships and access controls for complex APIs
* Run your application on-premises or in the cloud
* Use built-in push, geolocation, and file services for mobile use cases
* Easily create client apps using Android, iOS, and JavaScript SDKs
* Create dynamic end-to-end REST APIs with little or no coding.
* Access data from Oracle, MySQL, PostgreSQL, MS SQL Server, MongoDB, SOAP and other REST APIs.
* Incorporate model relationships and access controls for complex APIs.
* Use built-in push, geolocation, and file services for mobile apps.
* Easily create client apps using Android, iOS, and JavaScript SDKs.
* Run your application on-premises or in the cloud.

LoopBack consists of:

* A library of Node.js modules.
* A command line tool, `slc`, for creating and working with LoopBack applications.
* Client SDKs for native and web-based mobile clients.
* [Yeoman](http://yeoman.io/) generators for scaffolding applications.
* Client SDKs for iOS, Android, and web clients.

For more details, see http://loopback.io/.

## LoopBack modules

In addition to the [main LoopBack module](https://github.com/strongloop/loopback), LoopBack consists of numerous other modules that implement specific functionality,
as illustrated below:
The LoopBack framework includes of a set of Node.js modules that you can use independently or together.

![LoopBack modules](https://github.com/strongloop/loopback/raw/master/docs/assets/lb-modules.png "LoopBack modules")

* Frameworks
* [loopback](https://github.com/strongloop/loopback)
* [loopback-datasource-juggler](https://github.com/strongloop/loopback-datasource-juggler)
* [strong-remoting](https://github.com/strongloop/strong-remoting)

* Enterprise Connectors
* [loopback-connector-mongodb](https://github.com/strongloop/loopback-connector-mongodb)
* [loopback-connector-mysql](https://github.com/strongloop/loopback-connector-mysql)
* [loopback-connector-oracle](https://github.com/strongloop/loopback-connector-oracle)
* [loopback-connector-mssql](https://github.com/strongloop/loopback-connector-mssql)
* [loopback-connector-postgresql](https://github.com/strongloop/loopback-connector-postgresql)
* [loopback-connector-rest](https://github.com/strongloop/loopback-connector-rest)
* [loopback-connector-soap](https://github.com/strongloop/loopback-connector-soap)

* Mobile Components
* [loopback-component-push](https://github.com/strongloop/loopback-component-push)
* [loopback-component-storage](https://github.com/strongloop/loopback-component-storage)

* Security Components
* [loopback-component-passport](https://github.com/strongloop/loopback-component-passport)

* Clients
* [loopback-sdk-ios](https://github.com/strongloop/loopback-sdk-ios)
* [loopback-sdk-android](https://github.com/strongloop/loopback-sdk-android)
* [loopback-sdk-angular](https://github.com/strongloop/loopback-sdk-angular)
### Core
* [loopback](https://github.com/strongloop/loopback)
* [loopback-datasource-juggler](https://github.com/strongloop/loopback-datasource-juggler)
* [strong-remoting](https://github.com/strongloop/strong-remoting)

### Connectors
* [loopback-connector-mongodb](https://github.com/strongloop/loopback-connector-mongodb)
* [loopback-connector-mysql](https://github.com/strongloop/loopback-connector-mysql)
* [loopback-connector-postgresql](https://github.com/strongloop/loopback-connector-postgresql)
* [loopback-connector-rest](https://github.com/strongloop/loopback-connector-rest)

### Enterprise Connectors
* [loopback-connector-oracle](https://github.com/strongloop/loopback-connector-oracle)
* [loopback-connector-mssql](https://github.com/strongloop/loopback-connector-mssql)
* [loopback-connector-soap](https://github.com/strongloop/loopback-connector-soap)
* [loopback-connector-atg](https://github.com/strongloop/loopback-connector-atg)

### Components
* [loopback-component-push](https://github.com/strongloop/loopback-component-push)
* [loopback-component-storage](https://github.com/strongloop/loopback-component-storage)
* [loopback-component-passport](https://github.com/strongloop/loopback-component-passport)

### Client SDKs
* [loopback-sdk-ios](https://github.com/strongloop/loopback-sdk-ios)
* [loopback-sdk-android](https://github.com/strongloop/loopback-sdk-android)
* [loopback-sdk-angular](https://github.com/strongloop/loopback-sdk-angular)
* [loopback-sdk-angular-cli](https://github.com/strongloop/loopback-sdk-angular-cli)
* [grunt-loopback-sdk-angular](https://github.com/strongloop/grunt-loopback-sdk-angular)

* Tools
* [loopback-explorer](https://github.com/strongloop/loopback-explorer)
* [loopback-workspace](https://github.com/strongloop/loopback-workspace)
* [strong-cli](https://github.com/strongloop/strong-cli)

* Examples
* [loopback-example-database](https://github.com/strongloop/loopback-example-database)
* [loopback-example-datagraph](https://github.com/strongloop/loopback-example-datagraph)
* [loopback-example-full-stack](https://github.com/strongloop/loopback-example-full-stack)
* [loopback-example-office-supplies](https://github.com/strongloop/loopback-example-office-supplies)
* [loopback-example-todo](https://github.com/strongloop/loopback-example-todo)
* [loopback-example-access-control](https://github.com/strongloop/loopback-example-access-control)
* [loopback-example-proxy](https://github.com/strongloop/loopback-example-proxy)
* [strongloop-community/loopback-examples-ios](https://github.com/strongloop-community/loopback-examples-ios)
* [loopback-example-ssl](https://github.com/strongloop/loopback-example-ssl)
### Tools
* [loopback-explorer](https://github.com/strongloop/loopback-explorer)
* [loopback-workspace](https://github.com/strongloop/loopback-workspace)
* [generator-loopback](https://github.com/strongloop/generator-loopback)

### Examples

* [loopback-example-app](https://github.com/strongloop/loopback-example-app)
* [loopback-example-database](https://github.com/strongloop/loopback-example-database)
* [loopback-example-datagraph](https://github.com/strongloop/loopback-example-datagraph)
* [loopback-example-full-stack](https://github.com/strongloop/loopback-example-full-stack)
* [loopback-example-office-supplies](https://github.com/strongloop/loopback-example-office-supplies)
* [loopback-example-todo](https://github.com/strongloop/loopback-example-todo)
* [loopback-example-access-control](https://github.com/strongloop/loopback-example-access-control)
* [loopback-example-proxy](https://github.com/strongloop/loopback-example-proxy)
* [strongloop-community/loopback-examples-ios](https://github.com/strongloop-community/loopback-examples-ios)
* [loopback-example-ssl](https://github.com/strongloop/loopback-example-ssl)

## Resources

* [Documentation](http://docs.strongloop.com/display/LB/LoopBack).
* [API documentation](http://apidocs.strongloop.com/loopback).
* [LoopBack Google Group](https://groups.google.com/forum/#!forum/loopbackjs).
* [GitHub issues](https://github.com/strongloop/loopback/issues).
* Read more about the [LoopBack's features](https://github.com/strongloop/loopback/wiki/Features).

## Contributing

Expand Down
Binary file modified docs/assets/lb-modules.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,11 @@ app.model = function (Model, config) {

if (isPublic && Model.sharedClass) {
this.remotes().addClass(Model.sharedClass);
if (Model.settings.trackChanges && Model.Change)
if (Model.settings.trackChanges && Model.Change) {
this.remotes().addClass(Model.Change.sharedClass);
}
clearHandlerCache(this);
this.emit('modelRemoted', Model.sharedClass);
}

Model.shared = isPublic;
Expand Down
5 changes: 5 additions & 0 deletions lib/browser-express.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
var EventEmitter = require('events').EventEmitter;
var util = require('util');

module.exports = browserExpress;

function browserExpress() {
Expand All @@ -10,6 +13,8 @@ function BrowserExpress() {
this.settings = {};
}

util.inherits(BrowserExpress, EventEmitter);

BrowserExpress.prototype.set = function(key, value) {
if (arguments.length == 1) {
return this.get(key);
Expand Down
15 changes: 11 additions & 4 deletions lib/connectors/mail.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,17 @@ MailConnector.prototype.setupTransport = function(setting) {
connector.transports = connector.transports || [];
connector.transportsIndex = connector.transportsIndex || {};

var transportModuleName = 'nodemailer-' + (setting.type || 'STUB').toLowerCase() + '-transport';
var transportModule = require(transportModuleName);

var transport = mailer.createTransport(transportModule(setting));
var transport;
var transportType = (setting.type || 'STUB').toLowerCase();
if (transportType === 'direct') {
transport = mailer.createTransport();
} else if (transportType === 'smtp') {
transport = mailer.createTransport(setting);
} else {
var transportModuleName = 'nodemailer-' + transportType + '-transport';
var transportModule = require(transportModuleName);
transport = mailer.createTransport(transportModule(setting));
}

connector.transportsIndex[setting.type] = transport;
connector.transports.push(transport);
Expand Down
19 changes: 12 additions & 7 deletions lib/models/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ Model.setup = function () {

var idDesc = ModelCtor.modelName + ' id';
ModelCtor.sharedCtor.accepts = [
{arg: 'id', type: 'any', http: {source: 'path'}, description: idDesc}
{arg: 'id', type: 'any', required: true, http: {source: 'path'},
description: idDesc}
// {arg: 'instance', type: 'object', http: {source: 'body'}}
];

Expand Down Expand Up @@ -347,6 +348,7 @@ Model.belongsToRemoting = function(relationName, relation, define) {
}

Model.hasManyRemoting = function (relationName, relation, define) {
var toModelName = relation.modelTo.modelName;
var findByIdFunc = this.prototype['__findById__' + relationName];
define('__findById__' + relationName, {
isStatic: false,
Expand All @@ -355,7 +357,7 @@ Model.hasManyRemoting = function (relationName, relation, define) {
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
description: 'Find a related item by id for ' + relationName,
returns: {arg: 'result', type: relation.modelTo.modelName, root: true}
returns: {arg: 'result', type: toModelName, root: true}
}, findByIdFunc);

var destroyByIdFunc = this.prototype['__destroyById__' + relationName];
Expand All @@ -373,11 +375,14 @@ Model.hasManyRemoting = function (relationName, relation, define) {
define('__updateById__' + relationName, {
isStatic: false,
http: {verb: 'put', path: '/' + relationName + '/:fk'},
accepts: {arg: 'fk', type: 'any',
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
accepts: [
{arg: 'fk', type: 'any',
description: 'Foreign key for ' + relationName, required: true,
http: {source: 'path'}},
{arg: 'data', type: toModelName, http: {source: 'body'}}
],
description: 'Update a related item by id for ' + relationName,
returns: {arg: 'result', type: relation.modelTo.modelName, root: true}
returns: {arg: 'result', type: toModelName, root: true}
}, updateByIdFunc);

if (relation.modelThrough) {
Expand Down Expand Up @@ -432,7 +437,7 @@ Model.scopeRemoting = function(relationName, relation, define) {
define('__create__' + relationName, {
isStatic: false,
http: {verb: 'post', path: '/' + relationName},
accepts: {arg: 'data', type: 'object', http: {source: 'body'}},
accepts: {arg: 'data', type: toModelName, http: {source: 'body'}},
description: 'Creates a new instance in ' + relationName + ' of this model.',
returns: {arg: 'data', type: toModelName, root: true}
});
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "loopback",
"description": "LoopBack: Open API Framework for Node.js",
"description": "LoopBack: Open Source Framework for Node.js",
"homepage": "http://loopback.io",
"keywords": [
"restful",
Expand All @@ -26,7 +26,7 @@
"mobile",
"mBaaS"
],
"version": "2.0.0",
"version": "2.0.1",
"scripts": {
"test": "grunt mocha-and-karma"
},
Expand Down
12 changes: 12 additions & 0 deletions test/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ describe('app', function() {
expect(app.models.Color).to.equal(Color);
});

it("emits a `modelRemoted` event", function() {
var Color = PersistedModel.extend('color', {name: String});
Color.shared = true;
var remotedClass;
app.on('modelRemoted', function(sharedClass) {
remotedClass = sharedClass;
});
app.model(Color);
expect(remotedClass).to.exist;
expect(remotedClass).to.eql(Color.sharedClass);
});

it.onServer('updates REST API when a new model is added', function(done) {
app.use(loopback.rest());
request(app).get('/colors').expect(404, function(err, res) {
Expand Down
24 changes: 24 additions & 0 deletions test/email.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
var loopback = require('../');
var MyEmail;
var assert = require('assert');
var MailConnector = require('../lib/connectors/mail');

describe('Email connector', function () {
it('should set up SMTP', function () {
var connector = new MailConnector({transports: [
{type: 'smtp', service: 'gmail'}
]});
assert(connector.transportForName('smtp'));
});

it('should set up DIRECT', function () {
var connector = new MailConnector({transports: [
{type: 'direct', name: 'localhost'}
]});
assert(connector.transportForName('direct'));
});

it('should set up STUB', function () {
var connector = new MailConnector({transports: [
{type: 'stub', service: 'gmail'}
]});
assert(connector.transportForName('stub'));
});
});

describe('Email and SMTP', function () {
beforeEach(function() {
Expand Down

0 comments on commit 0e3187c

Please sign in to comment.