Update eslint to loopback config v5

Notable side-effects:
 - loopback no longer exports "caller" and "arguments" properties
 - kv-memory connector is now properly added to the connector registry
 - the file "test/support.js" was finally removed
This commit is contained in:
Loay 2016-11-15 16:46:23 -05:00 committed by Miroslav Bajtoš
parent ef0478cc97
commit 06cb481c3f
113 changed files with 1275 additions and 1151 deletions

View File

@ -5,6 +5,7 @@
"ignoreComments": true,
"ignoreUrls": true,
"ignorePattern": "^\\s*var\\s.+=\\s*(require\\s*\\()|(/)"
}]
}],
"no-unused-expressions": "off",
}
}

View File

@ -4,6 +4,7 @@
// License text available at https://opensource.org/licenses/MIT
/*global module:false*/
'use strict';
module.exports = function(grunt) {
// Do not report warnings from unit-tests exercising deprecated paths
process.env.NO_DEPRECATION = 'loopback';
@ -201,7 +202,7 @@ module.exports = function(grunt) {
},
// Add browserify to preprocessors
preprocessors: { 'test/e2e/*': ['browserify'] },
preprocessors: {'test/e2e/*': ['browserify']},
},
},
},

View File

@ -7,6 +7,7 @@
* Module Dependencies.
*/
'use strict';
var g = require('../../lib/globalize');
var loopback = require('../../lib/loopback');
var assert = require('assert');
@ -47,7 +48,7 @@ module.exports = function(AccessToken) {
* ```
*/
AccessToken.ANONYMOUS = new AccessToken({ id: '$anonymous' });
AccessToken.ANONYMOUS = new AccessToken({id: '$anonymous'});
/**
* Create a cryptographically random access token id.

View File

@ -3,13 +3,11 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
/*!
Schema ACL options
Object level permissions, for example, an album owned by a user
Factors to be authorized against:
* model name: Album
* model instance properties: userId of the album, friends, shared
* methods
@ -21,19 +19,15 @@
** none
** everyone
** relations: owner/friend/granted
Class level permissions, for example, Album
* model name: Album
* methods
URL/Route level permissions
* url pattern
* application id
* ip addresses
* http headers
Map to oAuth 2.0 scopes
*/
var g = require('../../lib/globalize');
@ -331,10 +325,10 @@ module.exports = function(ACL) {
principalId = principalId.toString();
}
property = property || ACL.ALL;
var propertyQuery = (property === ACL.ALL) ? undefined : { inq: [property, ACL.ALL] };
var propertyQuery = (property === ACL.ALL) ? undefined : {inq: [property, ACL.ALL]};
accessType = accessType || ACL.ALL;
var accessTypeQuery = (accessType === ACL.ALL) ? undefined :
{ inq: [accessType, ACL.ALL, ACL.EXECUTE] };
{inq: [accessType, ACL.ALL, ACL.EXECUTE]};
var req = new AccessRequest(model, property, accessType);
@ -352,8 +346,8 @@ module.exports = function(ACL) {
}
var self = this;
this.find({ where: { principalType: principalType, principalId: principalId,
model: model, property: propertyQuery, accessType: accessTypeQuery }},
this.find({where: {principalType: principalType, principalId: principalId,
model: model, property: propertyQuery, accessType: accessTypeQuery}},
function(err, dynACLs) {
if (err) {
if (callback) callback(err);
@ -408,21 +402,21 @@ module.exports = function(ACL) {
var modelName = context.modelName;
var methodNames = context.methodNames;
var propertyQuery = (property === ACL.ALL) ? undefined : { inq: methodNames.concat([ACL.ALL]) };
var propertyQuery = (property === ACL.ALL) ? undefined : {inq: methodNames.concat([ACL.ALL])};
var accessTypeQuery = (accessType === ACL.ALL) ?
undefined :
(accessType === ACL.REPLICATE) ?
{ inq: [ACL.REPLICATE, ACL.WRITE, ACL.ALL] } :
{ inq: [accessType, ACL.ALL] };
{inq: [ACL.REPLICATE, ACL.WRITE, ACL.ALL]} :
{inq: [accessType, ACL.ALL]};
var req = new AccessRequest(modelName, property, accessType, ACL.DEFAULT, methodNames);
var effectiveACLs = [];
var staticACLs = self.getStaticACLs(model.modelName, property);
this.find({ where: { model: model.modelName, property: propertyQuery,
accessType: accessTypeQuery }}, function(err, acls) {
this.find({where: {model: model.modelName, property: propertyQuery,
accessType: accessTypeQuery}}, function(err, acls) {
if (err) {
if (callback) callback(err);
return;
@ -525,15 +519,15 @@ module.exports = function(ACL) {
this.resolveRelatedModels();
switch (type) {
case ACL.ROLE:
this.roleModel.findOne({ where: { or: [{ name: id }, { id: id }] }}, cb);
this.roleModel.findOne({where: {or: [{name: id}, {id: id}]}}, cb);
break;
case ACL.USER:
this.userModel.findOne(
{ where: { or: [{ username: id }, { email: id }, { id: id }] }}, cb);
{where: {or: [{username: id}, {email: id}, {id: id}]}}, cb);
break;
case ACL.APP:
this.applicationModel.findOne(
{ where: { or: [{ name: id }, { email: id }, { id: id }] }}, cb);
{where: {or: [{name: id}, {email: id}, {id: id}]}}, cb);
break;
default:
process.nextTick(function() {

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var utils = require('../../lib/utils');
@ -70,18 +71,6 @@ function generateKey(hmacKey, algorithm, encoding) {
*/
module.exports = function(Application) {
// Workaround for https://github.com/strongloop/loopback/issues/292
Application.definition.rawProperties.created.default =
Application.definition.properties.created.default = function() {
return new Date();
};
// Workaround for https://github.com/strongloop/loopback/issues/292
Application.definition.rawProperties.modified.default =
Application.definition.properties.modified.default = function() {
return new Date();
};
/*!
* A hook to generate keys before creation
* @param next
@ -126,7 +115,7 @@ module.exports = function(Application) {
}
cb = cb || utils.createPromiseCallback();
var props = { owner: owner, name: name };
var props = {owner: owner, name: name};
for (var p in options) {
if (!(p in props)) {
props[p] = options[p];

View File

@ -118,7 +118,13 @@
"description": "Status of the application, production/sandbox/disabled"
},
"created": "date",
"modified": "date"
"created": {
"type": "date",
"defaultFn": "now"
},
"modified": {
"type": "date",
"defaultFn": "now"
}
}
}

View File

@ -7,12 +7,13 @@
* Module Dependencies.
*/
'use strict';
var g = require('../../lib/globalize');
var PersistedModel = require('../../lib/loopback').PersistedModel;
var loopback = require('../../lib/loopback');
var utils = require('../../lib/utils');
var crypto = require('crypto');
var CJSON = { stringify: require('canonical-json') };
var CJSON = {stringify: require('canonical-json')};
var async = require('async');
var assert = require('assert');
var debug = require('debug')('loopback:change');
@ -113,7 +114,7 @@ module.exports = function(Change) {
var msg = g.f('Cannot rectify %s changes:\n%s', modelName, desc);
err = new Error(msg);
err.details = { errors: errors };
err.details = {errors: errors};
return callback(err);
}
callback();
@ -404,7 +405,7 @@ module.exports = function(Change) {
callback = callback || utils.createPromiseCallback();
if (!Array.isArray(remoteChanges) || remoteChanges.length === 0) {
callback(null, { deltas: [], conflicts: [] });
callback(null, {deltas: [], conflicts: []});
return callback.promise;
}
var remoteChangeIndex = {};
@ -419,7 +420,7 @@ module.exports = function(Change) {
this.find({
where: {
modelName: modelName,
modelId: { inq: modelIds },
modelId: {inq: modelIds},
},
}, function(err, allLocalChanges) {
if (err) return callback(err);
@ -674,7 +675,7 @@ module.exports = function(Change) {
if (err) return cb(err);
conflict.SourceModel.updateLastChange(
conflict.modelId,
{ prev: targetChange.rev },
{prev: targetChange.rev},
cb);
});
};
@ -708,7 +709,7 @@ module.exports = function(Change) {
}
var inst = new conflict.SourceModel(
target.toObject(),
{ persisted: true });
{persisted: true});
inst.save(done);
});

View File

@ -7,6 +7,7 @@
* Module Dependencies.
*/
'use strict';
var assert = require('assert');
/**
@ -41,8 +42,8 @@ module.exports = function(Checkpoint) {
};
Checkpoint._getSingleton = function(cb) {
var query = { limit: 1 }; // match all instances, return only one
var initialData = { seq: 1 };
var query = {limit: 1}; // match all instances, return only one
var initialData = {seq: 1};
this.findOrCreate(query, initialData, cb);
};
@ -59,7 +60,7 @@ module.exports = function(Checkpoint) {
var originalSeq = cp.seq;
cp.seq++;
// Update the checkpoint but only if it was not changed under our hands
Checkpoint.updateAll({ id: cp.id, seq: originalSeq }, { seq: cp.seq }, function(err, info) {
Checkpoint.updateAll({id: cp.id, seq: originalSeq}, {seq: cp.seq}, function(err, info) {
if (err) return cb(err);
// possible outcomes
// 1) seq was updated to seq+1 - exactly what we wanted!

View File

@ -3,20 +3,21 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
/**
* Email model. Extends LoopBack base [Model](#model-new-model).
* @property {String} to Email addressee. Required.
* @property {String} from Email sender address. Required.
* @property {String} subject Email subject string. Required.
* @property {String} text Text body of email.
* @property {String} html HTML body of email.
*
* @class Email
* @inherits {Model}
*/
'use strict';
var g = require('../../lib/globalize');
/**
* Email model. Extends LoopBack base [Model](#model-new-model).
* @property {String} to Email addressee. Required.
* @property {String} from Email sender address. Required.
* @property {String} subject Email subject string. Required.
* @property {String} text Text body of email.
* @property {String} html HTML body of email.
*
* @class Email
* @inherits {Model}
*/
module.exports = function(Email) {
/**
* Send an email with the given `options`.

View File

@ -1,3 +1,9 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
/**
@ -164,52 +170,52 @@ module.exports = function(KeyValueModel) {
this.remoteMethod('get', {
accepts: {
arg: 'key', type: 'string', required: true,
http: { source: 'path' },
http: {source: 'path'},
},
returns: { arg: 'value', type: 'any', root: true },
http: { path: '/:key', verb: 'get' },
rest: { after: convertNullToNotFoundError },
returns: {arg: 'value', type: 'any', root: true},
http: {path: '/:key', verb: 'get'},
rest: {after: convertNullToNotFoundError},
});
this.remoteMethod('set', {
accepts: [
{ arg: 'key', type: 'string', required: true,
http: { source: 'path' }},
{ arg: 'value', type: 'any', required: true,
http: { source: 'body' }},
{ arg: 'ttl', type: 'number',
http: { source: 'query' },
description: 'time to live in milliseconds' },
{arg: 'key', type: 'string', required: true,
http: {source: 'path'}},
{arg: 'value', type: 'any', required: true,
http: {source: 'body'}},
{arg: 'ttl', type: 'number',
http: {source: 'query'},
description: 'time to live in milliseconds'},
],
http: { path: '/:key', verb: 'put' },
http: {path: '/:key', verb: 'put'},
});
this.remoteMethod('expire', {
accepts: [
{ arg: 'key', type: 'string', required: true,
http: { source: 'path' }},
{ arg: 'ttl', type: 'number', required: true,
http: { source: 'form' }},
{arg: 'key', type: 'string', required: true,
http: {source: 'path'}},
{arg: 'ttl', type: 'number', required: true,
http: {source: 'form'}},
],
http: { path: '/:key/expire', verb: 'put' },
http: {path: '/:key/expire', verb: 'put'},
});
this.remoteMethod('ttl', {
accepts: {
arg: 'key', type: 'string', required: true,
http: { source: 'path' },
http: {source: 'path'},
},
returns: { arg: 'value', type: 'any', root: true },
http: { path: '/:key/ttl', verb: 'get' },
returns: {arg: 'value', type: 'any', root: true},
http: {path: '/:key/ttl', verb: 'get'},
});
this.remoteMethod('keys', {
accepts: {
arg: 'filter', type: 'object', required: false,
http: { source: 'query' },
http: {source: 'query'},
},
returns: { arg: 'keys', type: ['string'], root: true },
http: { path: '/keys', verb: 'get' },
returns: {arg: 'keys', type: ['string'], root: true},
http: {path: '/keys', verb: 'get'},
});
};
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../lib/loopback');
/**

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../lib/loopback');
var debug = require('debug')('loopback:security:role');
var assert = require('assert');
@ -20,18 +21,6 @@ assert(RoleMapping, 'RoleMapping model must be defined before Role model');
* @header Role object
*/
module.exports = function(Role) {
// Workaround for https://github.com/strongloop/loopback/issues/292
Role.definition.rawProperties.created.default =
Role.definition.properties.created.default = function() {
return new Date();
};
// Workaround for https://github.com/strongloop/loopback/issues/292
Role.definition.rawProperties.modified.default =
Role.definition.properties.modified.default = function() {
return new Date();
};
Role.resolveRelatedModels = function() {
if (!this.userModel) {
var reg = this.registry;
@ -98,7 +87,7 @@ module.exports = function(Role) {
}
roleModel.roleMappingModel.find({
where: { roleId: context.id, principalType: principalType },
where: {roleId: context.id, principalType: principalType},
}, function(err, mappings) {
var ids;
if (err) {
@ -108,7 +97,7 @@ module.exports = function(Role) {
return m.principalId;
});
query.where = query.where || {};
query.where.id = { inq: ids };
query.where.id = {inq: ids};
model.find(query, function(err, models) {
callback(err, models);
});
@ -330,7 +319,7 @@ module.exports = function(Role) {
}
var roleMappingModel = this.roleMappingModel;
this.findOne({ where: { name: role }}, function(err, result) {
this.findOne({where: {name: role}}, function(err, result) {
if (err) {
if (callback) callback(err);
return;
@ -353,8 +342,8 @@ module.exports = function(Role) {
}
if (principalType && principalId) {
roleMappingModel.findOne({ where: { roleId: roleId,
principalType: principalType, principalId: principalId }},
roleMappingModel.findOne({where: {roleId: roleId,
principalType: principalType, principalId: principalId}},
function(err, result) {
debug('Role mapping found: %j', result);
done(!err && result); // The only arg is the result
@ -429,8 +418,8 @@ module.exports = function(Role) {
if (principalType && principalId) {
// Please find() treat undefined matches all values
inRoleTasks.push(function(done) {
roleMappingModel.find({ where: { principalType: principalType,
principalId: principalId }}, function(err, mappings) {
roleMappingModel.find({where: {principalType: principalType,
principalId: principalId}}, function(err, mappings) {
debug('Role mappings found: %s %j', err, mappings);
if (err) {
if (done) done(err);
@ -451,5 +440,5 @@ module.exports = function(Role) {
});
};
Role.validatesUniquenessOf('name', { message: 'already exists' });
Role.validatesUniquenessOf('name', {message: 'already exists'});
};

View File

@ -13,8 +13,12 @@
},
"description": "string",
"created": "date",
"modified": "date"
"created": {
"defaultFn": "now"
},
"modified": {
"defaultFn": "now"
}
},
"relations": {
"principals": {

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('../../lib/loopback');
@ -41,7 +42,7 @@ module.exports = function(Scope) {
assert(aclModel,
'ACL model must be defined before Scope.checkPermission is called');
this.findOne({ where: { name: scope }}, function(err, scope) {
this.findOne({where: {name: scope}}, function(err, scope) {
if (err) {
if (callback) callback(err);
} else {

View File

@ -7,6 +7,7 @@
* Module Dependencies.
*/
'use strict';
var g = require('../../lib/globalize');
var isEmail = require('isemail');
var loopback = require('../../lib/loopback');
@ -219,7 +220,7 @@ module.exports = function(User) {
return fn.promise;
}
self.findOne({ where: query }, function(err, user) {
self.findOne({where: query}, function(err, user) {
var defaultError = new Error(g.f('login failed'));
defaultError.statusCode = 401;
defaultError.code = 'LOGIN_FAILED';
@ -306,14 +307,14 @@ module.exports = function(User) {
User.observe('before delete', function(ctx, next) {
var AccessToken = ctx.Model.relations.accessTokens.modelTo;
var pkName = ctx.Model.definition.idName() || 'id';
ctx.Model.find({ where: ctx.where, fields: [pkName] }, function(err, list) {
ctx.Model.find({where: ctx.where, fields: [pkName]}, function(err, list) {
if (err) return next(err);
var ids = list.map(function(u) { return u[pkName]; });
ctx.where = {};
ctx.where[pkName] = { inq: ids };
ctx.where[pkName] = {inq: ids};
AccessToken.destroyAll({ userId: { inq: ids }}, next);
AccessToken.destroyAll({userId: {inq: ids}}, next);
});
});
@ -431,7 +432,8 @@ module.exports = function(User) {
options.templateFn = options.templateFn || createVerificationEmailBody;
// Email model
var Email = options.mailer || this.constructor.email || registry.getModelByType(loopback.Email);
var Email =
options.mailer || this.constructor.email || registry.getModelByType(loopback.Email);
// Set a default token generation function if one is not provided
var tokenGenerator = options.generateVerificationToken || User.generateVerificationToken;
@ -479,7 +481,7 @@ module.exports = function(User) {
if (err) {
fn(err);
} else {
fn(null, { email: email, token: user.verificationToken, uid: user.id });
fn(null, {email: email, token: user.verificationToken, uid: user.id});
}
});
}
@ -493,7 +495,6 @@ module.exports = function(User) {
cb(null, body);
}
/**
* A default verification token generator which accepts the user the token is
* being generated for and a callback function to indicate completion.
@ -584,7 +585,7 @@ module.exports = function(User) {
} catch (err) {
return cb(err);
}
UserModel.findOne({ where: { email: options.email }}, function(err, user) {
UserModel.findOne({where: {email: options.email}}, function(err, user) {
if (err) {
return cb(err);
}
@ -603,7 +604,7 @@ module.exports = function(User) {
return cb(err);
}
user.accessTokens.create({ ttl: ttl }, function(err, accessToken) {
user.accessTokens.create({ttl: ttl}, function(err, accessToken) {
if (err) {
return cb(err);
}
@ -699,11 +700,11 @@ module.exports = function(User) {
UserModel.observe('before save', function beforeEmailUpdate(ctx, next) {
if (ctx.isNewInstance) return next();
if (!ctx.where && !ctx.instance) return next();
var where = ctx.where || { id: ctx.instance.id };
ctx.Model.find({ where: where }, function(err, userInstances) {
var where = ctx.where || {id: ctx.instance.id};
ctx.Model.find({where: where}, function(err, userInstances) {
if (err) return next(err);
ctx.hookState.originalUserData = userInstances.map(function(u) {
return { id: u.id, email: u.email };
return {id: u.id, email: u.email};
});
if (ctx.instance) {
var emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
@ -735,7 +736,7 @@ module.exports = function(User) {
return u.id;
});
if (!idsToExpire.length) return next();
AccessToken.deleteAll({ userId: { inq: idsToExpire }}, next);
AccessToken.deleteAll({userId: {inq: idsToExpire}}, next);
});
UserModel.remoteMethod(
@ -743,10 +744,10 @@ module.exports = function(User) {
{
description: 'Login a user with username/email and password.',
accepts: [
{ arg: 'credentials', type: 'object', required: true, http: { source: 'body' }},
{ arg: 'include', type: ['string'], http: { source: 'query' },
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}},
{arg: 'include', type: ['string'], http: {source: 'query'},
description: 'Related objects to include in the response. ' +
'See the description of return value for more details.' },
'See the description of return value for more details.'},
],
returns: {
arg: 'accessToken', type: 'object', root: true,
@ -757,7 +758,7 @@ module.exports = function(User) {
' - `user` - `U+007BUserU+007D` - Data of the currently logged in user. ' +
'{{(`include=user`)}}\n\n'),
},
http: { verb: 'post' },
http: {verb: 'post'},
}
);
@ -766,7 +767,7 @@ module.exports = function(User) {
{
description: 'Logout a user with access token.',
accepts: [
{ arg: 'access_token', type: 'string', required: true, http: function(ctx) {
{arg: 'access_token', type: 'string', required: true, http: function(ctx) {
var req = ctx && ctx.req;
var accessToken = req && req.accessToken;
var tokenID = accessToken && accessToken.id;
@ -776,7 +777,7 @@ module.exports = function(User) {
'from request headers.',
},
],
http: { verb: 'all' },
http: {verb: 'all'},
}
);
@ -785,11 +786,11 @@ module.exports = function(User) {
{
description: 'Confirm a user registration with email verification token.',
accepts: [
{ arg: 'uid', type: 'string', required: true },
{ arg: 'token', type: 'string', required: true },
{ arg: 'redirect', type: 'string' },
{arg: 'uid', type: 'string', required: true},
{arg: 'token', type: 'string', required: true},
{arg: 'redirect', type: 'string'},
],
http: { verb: 'get', path: '/confirm' },
http: {verb: 'get', path: '/confirm'},
}
);
@ -798,9 +799,9 @@ module.exports = function(User) {
{
description: 'Reset password for a user with email.',
accepts: [
{ arg: 'options', type: 'object', required: true, http: { source: 'body' }},
{arg: 'options', type: 'object', required: true, http: {source: 'body'}},
],
http: { verb: 'post', path: '/reset' },
http: {verb: 'post', path: '/reset'},
}
);
@ -838,8 +839,8 @@ module.exports = function(User) {
});
} else {
// Regular(Non-realm) users validation
UserModel.validatesUniquenessOf('email', { message: 'Email already exists' });
UserModel.validatesUniquenessOf('username', { message: 'User already exists' });
UserModel.validatesUniquenessOf('email', {message: 'Email already exists'});
UserModel.validatesUniquenessOf('username', {message: 'User already exists'});
}
return UserModel;

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
var loopback = require('../../');
var client = loopback();

View File

@ -3,18 +3,19 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../');
var CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', {
tax: { type: Number, default: 0.1 },
tax: {type: Number, default: 0.1},
price: Number,
item: String,
qty: { type: Number, default: 0 },
qty: {type: Number, default: 0},
cartId: Number,
});
CartItem.sum = function(cartId, callback) {
this.find({ where: { cartId: 1 }}, function(err, items) {
this.find({where: {cartId: 1}}, function(err, items) {
var total = items
.map(function(item) {
return item.total();
@ -29,8 +30,8 @@ CartItem.sum = function(cartId, callback) {
CartItem.remoteMethod('sum',
{
accepts: { arg: 'cartId', type: 'number' },
returns: { arg: 'total', type: 'number' },
accepts: {arg: 'cartId', type: 'number'},
returns: {arg: 'total', type: 'number'},
}
);

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../');
var server = module.exports = loopback();
var CartItem = require('./models').CartItem;
@ -17,9 +18,9 @@ CartItem.attachTo(memory);
// test data
CartItem.create([
{ item: 'red hat', qty: 6, price: 19.99, cartId: 1 },
{ item: 'green shirt', qty: 1, price: 14.99, cartId: 1 },
{ item: 'orange pants', qty: 58, price: 9.99, cartId: 1 },
{item: 'red hat', qty: 6, price: 19.99, cartId: 1},
{item: 'green shirt', qty: 1, price: 14.99, cartId: 1},
{item: 'orange pants', qty: 58, price: 9.99, cartId: 1},
]);
CartItem.sum(1, function(err, total) {

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
var loopback = require('../../');
var app = loopback();
@ -13,13 +14,13 @@ var schema = {
name: String,
};
app.dataSource('db', { connector: 'memory' });
app.dataSource('db', {connector: 'memory'});
var Color = app.registry.createModel('color', schema);
app.model(Color, { dataSource: 'db' });
app.model(Color, {dataSource: 'db'});
Color.create({ name: 'red' });
Color.create({ name: 'green' });
Color.create({ name: 'blue' });
Color.create({name: 'red'});
Color.create({name: 'green'});
Color.create({name: 'blue'});
app.listen(3000);

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
var loopback = require('../../');
var app = loopback();
@ -19,7 +20,7 @@ app.use(function saveHostToContext(req, res, next) {
app.use(loopback.rest());
var Color = loopback.createModel('color', { 'name': String });
var Color = loopback.createModel('color', {'name': String});
Color.beforeRemote('**', function(ctx, unused, next) {
// Inside LoopBack code, you can read the property from the context
var ns = loopback.getCurrentContext();
@ -27,8 +28,8 @@ Color.beforeRemote('**', function(ctx, unused, next) {
next();
});
app.dataSource('db', { connector: 'memory' });
app.model(Color, { dataSource: 'db' });
app.dataSource('db', {connector: 'memory'});
app.model(Color, {dataSource: 'db'});
app.listen(3000, function() {
g.log('A list of colors is available at {{http://localhost:3000/colors}}');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
var models = require('../../lib/models');
var loopback = require('../../');
@ -10,15 +11,14 @@ var app = loopback();
app.use(loopback.rest());
var dataSource = loopback.createDataSource('db', { connector: loopback.Memory });
var dataSource = loopback.createDataSource('db', {connector: loopback.Memory});
var Application = models.Application(dataSource);
app.model(Application);
var data = { pushSettings: [
{ 'platform': 'apns',
var data = {pushSettings: [
{'platform': 'apns',
'apns': {
'pushOptions': {
'gateway': 'gateway.sandbox.push.apple.com',
@ -34,14 +34,13 @@ var data = { pushSettings: [
'interval': 300,
},
}},
] };
]};
Application.create(data, function(err, data) {
g.log('Created: %s', data.toObject());
});
Application.register('rfeng', 'MyApp', { description: g.f('My first mobile application') },
Application.register('rfeng', 'MyApp', {description: g.f('My first mobile application')},
function(err, result) {
console.log(result.toObject());

View File

@ -3,13 +3,14 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../');
var app = loopback();
var db = app.dataSource('db', { connector: 'memory' });
var Color = app.registry.createModel('color', {}, { trackChanges: true });
app.model(Color, { dataSource: 'db' });
var Color2 = app.registry.createModel('color2', {}, { trackChanges: true });
app.model(Color2, { dataSource: 'db' });
var db = app.dataSource('db', {connector: 'memory'});
var Color = app.registry.createModel('color', {}, {trackChanges: true});
app.model(Color, {dataSource: 'db'});
var Color2 = app.registry.createModel('color2', {}, {trackChanges: true});
app.model(Color2, {dataSource: 'db'});
var target = Color2;
var source = Color;
var SPEED = process.env.SPEED || 100;
@ -70,9 +71,9 @@ run(steps);
function createSomeInitialSourceData() {
Color.create([
{ name: 'red' },
{ name: 'blue' },
{ name: 'green' },
{name: 'red'},
{name: 'blue'},
{name: 'green'},
]);
}
@ -98,11 +99,11 @@ function updateSomeTargetData() {
}
function createMoreSourceData() {
Color.create({ name: 'orange' });
Color.create({name: 'orange'});
}
function createEvenMoreSourceData() {
Color.create({ name: 'black' });
Color.create({name: 'black'});
}
function updateSomeSourceDataCausingAConflict() {
@ -118,9 +119,9 @@ function deleteAllSourceData() {
function createSomeNewSourceData() {
Color.create([
{ name: 'violet' },
{ name: 'amber' },
{ name: 'olive' },
{name: 'violet'},
{name: 'amber'},
{name: 'olive'},
]);
}

View File

@ -3,22 +3,22 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
var loopback = require('../../');
var app = loopback();
app.use(loopback.rest());
var dataSource = app.dataSource('db', { adapter: 'memory' });
var dataSource = app.dataSource('db', {adapter: 'memory'});
var Color = dataSource.define('color', {
'name': String,
});
Color.create({ name: 'red' });
Color.create({ name: 'green' });
Color.create({ name: 'blue' });
Color.create({name: 'red'});
Color.create({name: 'green'});
Color.create({name: 'blue'});
Color.all(function() {
console.log(arguments);

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
/**
* loopback ~ public api
*/

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('./loopback');
var debug = require('debug')('loopback:security:access-context');

View File

@ -7,6 +7,7 @@
* Module dependencies.
*/
'use strict';
var g = require('./globalize');
var DataSource = require('loopback-datasource-juggler').DataSource;
var Registry = require('./registry');
@ -484,7 +485,7 @@ function setSharedMethodSharedProperties(model, app, modelConfigs) {
});
// set sharedMethod.shared using the merged settings
var sharedMethods = model.sharedClass.methods({ includeDisabled: true });
var sharedMethods = model.sharedClass.methods({includeDisabled: true});
sharedMethods.forEach(function(sharedMethod) {
// use the specific setting if it exists
var hasSpecificSetting = settings.hasOwnProperty(sharedMethod.name);

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var EventEmitter = require('events').EventEmitter;
var util = require('util');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(registry) {
// NOTE(bajtos) we must use static require() due to browserify limitations

View File

@ -7,6 +7,7 @@
* Expose `Connector`.
*/
'use strict';
module.exports = Connector;
/**

View File

@ -7,6 +7,7 @@
* Dependencies.
*/
'use strict';
var g = require('../globalize');
var mailer = require('nodemailer');
var assert = require('assert');

View File

@ -7,6 +7,7 @@
* Expose `Memory`.
*/
'use strict';
module.exports = Memory;
/**

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('./globalize');
var juggler = require('loopback-datasource-juggler');
var remoting = require('strong-remoting');

View File

@ -3,8 +3,9 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var path = require('path');
var SG = require('strong-globalize');
SG.SetRootDir(path.join(__dirname, '..'), { autonomousMsgLoading: 'all' });
SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'});
module.exports = SG();

View File

@ -7,6 +7,7 @@
* Module dependencies.
*/
'use strict';
var express = require('express');
var loopbackExpress = require('./server-app');
var proto = require('./application');
@ -93,6 +94,8 @@ function createApplication(options) {
// and thus browserify can process them (include connectors in the bundle)
app.connector('memory', loopback.Memory);
app.connector('remote', loopback.Remote);
app.connector('kv-memory',
require('loopback-datasource-juggler/lib/connectors/kv-memory'));
if (loopback.localRegistry || options && options.localRegistry === true) {
// setup the app registry
@ -179,7 +182,7 @@ loopback.remoteMethod = function(fn, options) {
fn[key] = options[key];
});
}
fn.http = fn.http || { verb: 'get' };
fn.http = fn.http || {verb: 'get'};
};
/**

View File

@ -6,7 +6,7 @@
/*!
* Module Dependencies.
*/
'use strict';
var g = require('./globalize');
var assert = require('assert');
var RemoteObjects = require('strong-remoting');
@ -180,16 +180,16 @@ module.exports = function(registry) {
var idDesc = ModelCtor.modelName + ' id';
ModelCtor.sharedCtor.accepts = [
{ arg: 'id', type: 'any', required: true, http: { source: 'path' },
description: idDesc },
{arg: 'id', type: 'any', required: true, http: {source: 'path'},
description: idDesc},
// {arg: 'instance', type: 'object', http: {source: 'body'}}
];
ModelCtor.sharedCtor.http = [
{ path: '/:id' },
{path: '/:id'},
];
ModelCtor.sharedCtor.returns = { root: true };
ModelCtor.sharedCtor.returns = {root: true};
// before remote hook
ModelCtor.beforeRemote = function(name, fn) {
@ -326,7 +326,7 @@ module.exports = function(registry) {
Model._getAccessTypeForMethod = function(method) {
if (typeof method === 'string') {
method = { name: method };
method = {name: method};
}
assert(
typeof method === 'object',
@ -463,11 +463,11 @@ module.exports = function(registry) {
var pathName = (relation.options.http && relation.options.http.path) || relationName;
define('__get__' + relationName, {
isStatic: false,
http: { verb: 'get', path: '/' + pathName },
accepts: { arg: 'refresh', type: 'boolean', http: { source: 'query' }},
http: {verb: 'get', path: '/' + pathName},
accepts: {arg: 'refresh', type: 'boolean', http: {source: 'query'}},
accessType: 'READ',
description: format('Fetches belongsTo relation %s.', relationName),
returns: { arg: relationName, type: modelName, root: true },
returns: {arg: relationName, type: modelName, root: true},
}, fn);
};
@ -488,35 +488,35 @@ module.exports = function(registry) {
define('__get__' + relationName, {
isStatic: false,
http: { verb: 'get', path: '/' + pathName },
accepts: { arg: 'refresh', type: 'boolean', http: { source: 'query' }},
http: {verb: 'get', path: '/' + pathName},
accepts: {arg: 'refresh', type: 'boolean', http: {source: 'query'}},
description: format('Fetches hasOne relation %s.', relationName),
accessType: 'READ',
returns: { arg: relationName, type: relation.modelTo.modelName, root: true },
rest: { after: convertNullToNotFoundError.bind(null, toModelName) },
returns: {arg: relationName, type: relation.modelTo.modelName, root: true},
rest: {after: convertNullToNotFoundError.bind(null, toModelName)},
});
define('__create__' + relationName, {
isStatic: false,
http: { verb: 'post', path: '/' + pathName },
accepts: { arg: 'data', type: 'object', model: toModelName, http: { source: 'body' }},
http: {verb: 'post', path: '/' + pathName},
accepts: {arg: 'data', type: 'object', model: toModelName, http: {source: 'body'}},
description: format('Creates a new instance in %s of this model.', relationName),
accessType: 'WRITE',
returns: { arg: 'data', type: toModelName, root: true },
returns: {arg: 'data', type: toModelName, root: true},
});
define('__update__' + relationName, {
isStatic: false,
http: { verb: 'put', path: '/' + pathName },
accepts: { arg: 'data', type: 'object', model: toModelName, http: { source: 'body' }},
http: {verb: 'put', path: '/' + pathName},
accepts: {arg: 'data', type: 'object', model: toModelName, http: {source: 'body'}},
description: format('Update %s of this model.', relationName),
accessType: 'WRITE',
returns: { arg: 'data', type: toModelName, root: true },
returns: {arg: 'data', type: toModelName, root: true},
});
define('__destroy__' + relationName, {
isStatic: false,
http: { verb: 'delete', path: '/' + pathName },
http: {verb: 'delete', path: '/' + pathName},
description: format('Deletes %s of this model.', relationName),
accessType: 'WRITE',
});
@ -529,25 +529,25 @@ module.exports = function(registry) {
var findByIdFunc = this.prototype['__findById__' + relationName];
define('__findById__' + relationName, {
isStatic: false,
http: { verb: 'get', path: '/' + pathName + '/:fk' },
accepts: { arg: 'fk', type: 'any',
http: {verb: 'get', path: '/' + pathName + '/:fk'},
accepts: {arg: 'fk', type: 'any',
description: format('Foreign key for %s', relationName),
required: true,
http: { source: 'path' }},
http: {source: 'path'}},
description: format('Find a related item by id for %s.', relationName),
accessType: 'READ',
returns: { arg: 'result', type: toModelName, root: true },
rest: { after: convertNullToNotFoundError.bind(null, toModelName) },
returns: {arg: 'result', type: toModelName, root: true},
rest: {after: convertNullToNotFoundError.bind(null, toModelName)},
}, findByIdFunc);
var destroyByIdFunc = this.prototype['__destroyById__' + relationName];
define('__destroyById__' + relationName, {
isStatic: false,
http: { verb: 'delete', path: '/' + pathName + '/:fk' },
accepts: { arg: 'fk', type: 'any',
http: {verb: 'delete', path: '/' + pathName + '/:fk'},
accepts: {arg: 'fk', type: 'any',
description: format('Foreign key for %s', relationName),
required: true,
http: { source: 'path' }},
http: {source: 'path'}},
description: format('Delete a related item by id for %s.', relationName),
accessType: 'WRITE',
returns: [],
@ -556,17 +556,17 @@ module.exports = function(registry) {
var updateByIdFunc = this.prototype['__updateById__' + relationName];
define('__updateById__' + relationName, {
isStatic: false,
http: { verb: 'put', path: '/' + pathName + '/:fk' },
http: {verb: 'put', path: '/' + pathName + '/:fk'},
accepts: [
{ arg: 'fk', type: 'any',
{arg: 'fk', type: 'any',
description: format('Foreign key for %s', relationName),
required: true,
http: { source: 'path' }},
{ arg: 'data', type: 'object', model: toModelName, http: { source: 'body' }},
http: {source: 'path'}},
{arg: 'data', type: 'object', model: toModelName, http: {source: 'body'}},
],
description: format('Update a related item by id for %s.', relationName),
accessType: 'WRITE',
returns: { arg: 'result', type: toModelName, root: true },
returns: {arg: 'result', type: toModelName, root: true},
}, updateByIdFunc);
if (relation.modelThrough || relation.type === 'referencesMany') {
@ -577,31 +577,31 @@ module.exports = function(registry) {
// Restrict: only hasManyThrough relation can have additional properties
accepts.push({
arg: 'data', type: 'object', model: modelThrough.modelName,
http: { source: 'body' },
http: {source: 'body'},
});
}
var addFunc = this.prototype['__link__' + relationName];
define('__link__' + relationName, {
isStatic: false,
http: { verb: 'put', path: '/' + pathName + '/rel/:fk' },
accepts: [{ arg: 'fk', type: 'any',
http: {verb: 'put', path: '/' + pathName + '/rel/:fk'},
accepts: [{arg: 'fk', type: 'any',
description: format('Foreign key for %s', relationName),
required: true,
http: { source: 'path' }}].concat(accepts),
http: {source: 'path'}}].concat(accepts),
description: format('Add a related item by id for %s.', relationName),
accessType: 'WRITE',
returns: { arg: relationName, type: modelThrough.modelName, root: true },
returns: {arg: relationName, type: modelThrough.modelName, root: true},
}, addFunc);
var removeFunc = this.prototype['__unlink__' + relationName];
define('__unlink__' + relationName, {
isStatic: false,
http: { verb: 'delete', path: '/' + pathName + '/rel/:fk' },
accepts: { arg: 'fk', type: 'any',
http: {verb: 'delete', path: '/' + pathName + '/rel/:fk'},
accepts: {arg: 'fk', type: 'any',
description: format('Foreign key for %s', relationName),
required: true,
http: { source: 'path' }},
http: {source: 'path'}},
description: format('Remove the %s relation to an item by id.', relationName),
accessType: 'WRITE',
returns: [],
@ -612,14 +612,14 @@ module.exports = function(registry) {
var existsFunc = this.prototype['__exists__' + relationName];
define('__exists__' + relationName, {
isStatic: false,
http: { verb: 'head', path: '/' + pathName + '/rel/:fk' },
accepts: { arg: 'fk', type: 'any',
http: {verb: 'head', path: '/' + pathName + '/rel/:fk'},
accepts: {arg: 'fk', type: 'any',
description: format('Foreign key for %s', relationName),
required: true,
http: { source: 'path' }},
http: {source: 'path'}},
description: format('Check the existence of %s relation to an item by id.', relationName),
accessType: 'READ',
returns: { arg: 'exists', type: 'boolean', root: true },
returns: {arg: 'exists', type: 'boolean', root: true},
rest: {
// After hook to map exists to 200/404 for HEAD
after: function(ctx, cb) {
@ -658,37 +658,37 @@ module.exports = function(registry) {
define('__get__' + scopeName, {
isStatic: isStatic,
http: { verb: 'get', path: '/' + pathName },
accepts: { arg: 'filter', type: 'object' },
http: {verb: 'get', path: '/' + pathName},
accepts: {arg: 'filter', type: 'object'},
description: format('Queries %s of %s.', scopeName, this.modelName),
accessType: 'READ',
returns: { arg: scopeName, type: [toModelName], root: true },
returns: {arg: scopeName, type: [toModelName], root: true},
});
define('__create__' + scopeName, {
isStatic: isStatic,
http: { verb: 'post', path: '/' + pathName },
accepts: { arg: 'data', type: 'object', model: toModelName, http: { source: 'body' }},
http: {verb: 'post', path: '/' + pathName},
accepts: {arg: 'data', type: 'object', model: toModelName, http: {source: 'body'}},
description: format('Creates a new instance in %s of this model.', scopeName),
accessType: 'WRITE',
returns: { arg: 'data', type: toModelName, root: true },
returns: {arg: 'data', type: toModelName, root: true},
});
define('__delete__' + scopeName, {
isStatic: isStatic,
http: { verb: 'delete', path: '/' + pathName },
http: {verb: 'delete', path: '/' + pathName},
description: format('Deletes all %s of this model.', scopeName),
accessType: 'WRITE',
});
define('__count__' + scopeName, {
isStatic: isStatic,
http: { verb: 'get', path: '/' + pathName + '/count' },
accepts: { arg: 'where', type: 'object',
description: 'Criteria to match model instances' },
http: {verb: 'get', path: '/' + pathName + '/count'},
accepts: {arg: 'where', type: 'object',
description: 'Criteria to match model instances'},
description: format('Counts %s of %s.', scopeName, this.modelName),
accessType: 'READ',
returns: { arg: 'count', type: 'number' },
returns: {arg: 'count', type: 'number'},
});
};
@ -732,7 +732,7 @@ module.exports = function(registry) {
httpPath = pathName + '/:' + paramName;
acceptArgs = [
{
arg: paramName, type: 'any', http: { source: 'path' },
arg: paramName, type: 'any', http: {source: 'path'},
description: format('Foreign key for %s.', relation.name),
required: true,
},

View File

@ -6,7 +6,7 @@
/*!
* Module Dependencies.
*/
'use strict';
var g = require('./globalize');
var runtime = require('./runtime');
var assert = require('assert');
@ -642,10 +642,10 @@ module.exports = function(registry) {
accepts: {
arg: 'data', type: 'object', model: typeName, allowArray: true,
description: 'Model instance data',
http: { source: 'body' },
http: {source: 'body'},
},
returns: { arg: 'data', type: typeName, root: true },
http: { verb: 'post', path: '/' },
returns: {arg: 'data', type: typeName, root: true},
http: {verb: 'post', path: '/'},
});
var upsertOptions = {
@ -654,15 +654,15 @@ module.exports = function(registry) {
'into the data source.',
accessType: 'WRITE',
accepts: {
arg: 'data', type: 'object', model: typeName, http: { source: 'body' },
arg: 'data', type: 'object', model: typeName, http: {source: 'body'},
description: 'Model instance data',
},
returns: { arg: 'data', type: typeName, root: true },
http: [{ verb: 'patch', path: '/' }],
returns: {arg: 'data', type: typeName, root: true},
http: [{verb: 'patch', path: '/'}],
};
if (!options.replaceOnPUT) {
upsertOptions.http.unshift({ verb: 'put', path: '/' });
upsertOptions.http.unshift({verb: 'put', path: '/'});
}
setRemoting(PersistedModel, 'patchOrCreate', upsertOptions);
@ -671,15 +671,15 @@ module.exports = function(registry) {
accessType: 'WRITE',
accepts: {
arg: 'data', type: 'object', model: typeName,
http: { source: 'body' },
http: {source: 'body'},
description: 'Model instance data',
},
returns: { arg: 'data', type: typeName, root: true },
http: [{ verb: 'post', path: '/replaceOrCreate' }],
returns: {arg: 'data', type: typeName, root: true},
http: [{verb: 'post', path: '/replaceOrCreate'}],
};
if (options.replaceOnPUT) {
replaceOrCreateOptions.http.push({ verb: 'put', path: '/' });
replaceOrCreateOptions.http.push({verb: 'put', path: '/'});
}
setRemoting(PersistedModel, 'replaceOrCreate', replaceOrCreateOptions);
@ -690,23 +690,23 @@ module.exports = function(registry) {
'the data source based on the where criteria.',
accessType: 'WRITE',
accepts: [
{ arg: 'where', type: 'object', http: { source: 'query' },
description: 'Criteria to match model instances' },
{ arg: 'data', type: 'object', model: typeName, http: { source: 'body' },
description: 'An object of model property name/value pairs' },
{arg: 'where', type: 'object', http: {source: 'query'},
description: 'Criteria to match model instances'},
{arg: 'data', type: 'object', model: typeName, http: {source: 'body'},
description: 'An object of model property name/value pairs'},
],
returns: { arg: 'data', type: typeName, root: true },
http: { verb: 'post', path: '/upsertWithWhere' },
returns: {arg: 'data', type: typeName, root: true},
http: {verb: 'post', path: '/upsertWithWhere'},
});
setRemoting(PersistedModel, 'exists', {
description: 'Check whether a model instance exists in the data source.',
accessType: 'READ',
accepts: { arg: 'id', type: 'any', description: 'Model id', required: true },
returns: { arg: 'exists', type: 'boolean' },
accepts: {arg: 'id', type: 'any', description: 'Model id', required: true},
returns: {arg: 'exists', type: 'boolean'},
http: [
{ verb: 'get', path: '/:id/exists' },
{ verb: 'head', path: '/:id' },
{verb: 'get', path: '/:id/exists'},
{verb: 'head', path: '/:id'},
],
rest: {
// After hook to map exists to 200/404 for HEAD
@ -734,66 +734,65 @@ module.exports = function(registry) {
description: 'Find a model instance by {{id}} from the data source.',
accessType: 'READ',
accepts: [
{ arg: 'id', type: 'any', description: 'Model id', required: true,
http: { source: 'path' }},
{ arg: 'filter', type: 'object',
description: 'Filter defining fields and include' },
{arg: 'id', type: 'any', description: 'Model id', required: true,
http: {source: 'path'}},
{arg: 'filter', type: 'object',
description: 'Filter defining fields and include'},
],
returns: { arg: 'data', type: typeName, root: true },
http: { verb: 'get', path: '/:id' },
rest: { after: convertNullToNotFoundError },
returns: {arg: 'data', type: typeName, root: true},
http: {verb: 'get', path: '/:id'},
rest: {after: convertNullToNotFoundError},
});
var replaceByIdOptions = {
description: 'Replace attributes for a model instance and persist it into the data source.',
accessType: 'WRITE',
accepts: [
{ arg: 'id', type: 'any', description: 'Model id', required: true,
http: { source: 'path' }},
{ arg: 'data', type: 'object', model: typeName, http: { source: 'body' }, description:
'Model instance data' },
{arg: 'id', type: 'any', description: 'Model id', required: true,
http: {source: 'path'}},
{arg: 'data', type: 'object', model: typeName, http: {source: 'body'}, description:
'Model instance data'},
],
returns: { arg: 'data', type: typeName, root: true },
http: [{ verb: 'post', path: '/:id/replace' }],
returns: {arg: 'data', type: typeName, root: true},
http: [{verb: 'post', path: '/:id/replace'}],
};
if (options.replaceOnPUT) {
replaceByIdOptions.http.push({ verb: 'put', path: '/:id' });
replaceByIdOptions.http.push({verb: 'put', path: '/:id'});
}
setRemoting(PersistedModel, 'replaceById', replaceByIdOptions);
setRemoting(PersistedModel, 'find', {
description: 'Find all instances of the model matched by filter from the data source.',
accessType: 'READ',
accepts: { arg: 'filter', type: 'object', description:
'Filter defining fields, where, include, order, offset, and limit' },
returns: { arg: 'data', type: [typeName], root: true },
http: { verb: 'get', path: '/' },
accepts: {arg: 'filter', type: 'object', description:
'Filter defining fields, where, include, order, offset, and limit'},
returns: {arg: 'data', type: [typeName], root: true},
http: {verb: 'get', path: '/'},
});
setRemoting(PersistedModel, 'findOne', {
description: 'Find first instance of the model matched by filter from the data source.',
accessType: 'READ',
accepts: { arg: 'filter', type: 'object', description:
'Filter defining fields, where, include, order, offset, and limit' },
returns: { arg: 'data', type: typeName, root: true },
http: { verb: 'get', path: '/findOne' },
rest: { after: convertNullToNotFoundError },
accepts: {arg: 'filter', type: 'object', description:
'Filter defining fields, where, include, order, offset, and limit'},
returns: {arg: 'data', type: typeName, root: true},
http: {verb: 'get', path: '/findOne'},
rest: {after: convertNullToNotFoundError},
});
setRemoting(PersistedModel, 'destroyAll', {
description: 'Delete all matching records.',
accessType: 'WRITE',
accepts: { arg: 'where', type: 'object', description: 'filter.where object' },
accepts: {arg: 'where', type: 'object', description: 'filter.where object'},
returns: {
arg: 'count',
type: 'object',
description: 'The number of instances deleted',
root: true,
},
http: { verb: 'del', path: '/' },
http: {verb: 'del', path: '/'},
shared: false,
});
@ -802,10 +801,10 @@ module.exports = function(registry) {
description: 'Update instances of the model matched by {{where}} from the data source.',
accessType: 'WRITE',
accepts: [
{ arg: 'where', type: 'object', http: { source: 'query' },
description: 'Criteria to match model instances' },
{ arg: 'data', type: 'object', model: typeName, http: { source: 'body' },
description: 'An object of model property name/value pairs' },
{arg: 'where', type: 'object', http: {source: 'query'},
description: 'Criteria to match model instances'},
{arg: 'data', type: 'object', model: typeName, http: {source: 'body'},
description: 'An object of model property name/value pairs'},
],
returns: {
arg: 'info',
@ -818,25 +817,25 @@ module.exports = function(registry) {
},
root: true,
},
http: { verb: 'post', path: '/update' },
http: {verb: 'post', path: '/update'},
});
setRemoting(PersistedModel, 'deleteById', {
aliases: ['destroyById', 'removeById'],
description: 'Delete a model instance by {{id}} from the data source.',
accessType: 'WRITE',
accepts: { arg: 'id', type: 'any', description: 'Model id', required: true,
http: { source: 'path' }},
http: { verb: 'del', path: '/:id' },
returns: { arg: 'count', type: 'object', root: true },
accepts: {arg: 'id', type: 'any', description: 'Model id', required: true,
http: {source: 'path'}},
http: {verb: 'del', path: '/:id'},
returns: {arg: 'count', type: 'object', root: true},
});
setRemoting(PersistedModel, 'count', {
description: 'Count instances of the model matched by where from the data source.',
accessType: 'READ',
accepts: { arg: 'where', type: 'object', description: 'Criteria to match model instances' },
returns: { arg: 'count', type: 'number' },
http: { verb: 'get', path: '/count' },
accepts: {arg: 'where', type: 'object', description: 'Criteria to match model instances'},
returns: {arg: 'count', type: 'number'},
http: {verb: 'get', path: '/count'},
});
var updateAttributesOptions = {
@ -846,17 +845,17 @@ module.exports = function(registry) {
accessType: 'WRITE',
accepts: {
arg: 'data', type: 'object', model: typeName,
http: { source: 'body' },
http: {source: 'body'},
description: 'An object of model property name/value pairs',
},
returns: { arg: 'data', type: typeName, root: true },
http: [{ verb: 'patch', path: '/' }],
returns: {arg: 'data', type: typeName, root: true},
http: [{verb: 'patch', path: '/'}],
};
setRemoting(PersistedModel.prototype, 'patchAttributes', updateAttributesOptions);
if (!options.replaceOnPUT) {
updateAttributesOptions.http.unshift({ verb: 'put', path: '/' });
updateAttributesOptions.http.unshift({verb: 'put', path: '/'});
}
if (options.trackChanges || options.enableRemoteReplication) {
@ -864,12 +863,12 @@ module.exports = function(registry) {
description: 'Get a set of deltas and conflicts since the given checkpoint.',
accessType: 'READ',
accepts: [
{ arg: 'since', type: 'number', description: 'Find deltas since this checkpoint' },
{ arg: 'remoteChanges', type: 'array', description: 'an array of change objects',
http: { source: 'body' }},
{arg: 'since', type: 'number', description: 'Find deltas since this checkpoint'},
{arg: 'remoteChanges', type: 'array', description: 'an array of change objects',
http: {source: 'body'}},
],
returns: { arg: 'result', type: 'object', root: true },
http: { verb: 'post', path: '/diff' },
returns: {arg: 'result', type: 'object', root: true},
http: {verb: 'post', path: '/diff'},
});
setRemoting(PersistedModel, 'changes', {
@ -877,13 +876,13 @@ module.exports = function(registry) {
'Provide a filter object to reduce the number of results returned.',
accessType: 'READ',
accepts: [
{ arg: 'since', type: 'number', description:
'Only return changes since this checkpoint' },
{ arg: 'filter', type: 'object', description:
'Only include changes that match this filter' },
{arg: 'since', type: 'number', description:
'Only return changes since this checkpoint'},
{arg: 'filter', type: 'object', description:
'Only include changes that match this filter'},
],
returns: { arg: 'changes', type: 'array', root: true },
http: { verb: 'get', path: '/changes' },
returns: {arg: 'changes', type: 'array', root: true},
http: {verb: 'get', path: '/changes'},
});
setRemoting(PersistedModel, 'checkpoint', {
@ -893,15 +892,15 @@ module.exports = function(registry) {
// We need to allow this method for users that don't have full
// WRITE permissions.
accessType: 'REPLICATE',
returns: { arg: 'checkpoint', type: 'object', root: true },
http: { verb: 'post', path: '/checkpoint' },
returns: {arg: 'checkpoint', type: 'object', root: true},
http: {verb: 'post', path: '/checkpoint'},
});
setRemoting(PersistedModel, 'currentCheckpoint', {
description: 'Get the current checkpoint.',
accessType: 'READ',
returns: { arg: 'checkpoint', type: 'object', root: true },
http: { verb: 'get', path: '/checkpoint' },
returns: {arg: 'checkpoint', type: 'object', root: true},
http: {verb: 'get', path: '/checkpoint'},
});
setRemoting(PersistedModel, 'createUpdates', {
@ -910,27 +909,27 @@ module.exports = function(registry) {
// It is called by the replication algorithm to compile a list
// of changes to apply on the target.
accessType: 'READ',
accepts: { arg: 'deltas', type: 'array', http: { source: 'body' }},
returns: { arg: 'updates', type: 'array', root: true },
http: { verb: 'post', path: '/create-updates' },
accepts: {arg: 'deltas', type: 'array', http: {source: 'body'}},
returns: {arg: 'updates', type: 'array', root: true},
http: {verb: 'post', path: '/create-updates'},
});
setRemoting(PersistedModel, 'bulkUpdate', {
description: 'Run multiple updates at once. Note: this is not atomic.',
accessType: 'WRITE',
accepts: { arg: 'updates', type: 'array' },
http: { verb: 'post', path: '/bulk-update' },
accepts: {arg: 'updates', type: 'array'},
http: {verb: 'post', path: '/bulk-update'},
});
setRemoting(PersistedModel, 'findLastChange', {
description: 'Get the most recent change record for this instance.',
accessType: 'READ',
accepts: {
arg: 'id', type: 'any', required: true, http: { source: 'path' },
arg: 'id', type: 'any', required: true, http: {source: 'path'},
description: 'Model id',
},
returns: { arg: 'result', type: this.Change.modelName, root: true },
http: { verb: 'get', path: '/:id/changes/last' },
returns: {arg: 'result', type: this.Change.modelName, root: true},
http: {verb: 'get', path: '/:id/changes/last'},
});
setRemoting(PersistedModel, 'updateLastChange', {
@ -940,16 +939,16 @@ module.exports = function(registry) {
accessType: 'WRITE',
accepts: [
{
arg: 'id', type: 'any', required: true, http: { source: 'path' },
arg: 'id', type: 'any', required: true, http: {source: 'path'},
description: 'Model id',
},
{
arg: 'data', type: 'object', model: typeName, http: { source: 'body' },
arg: 'data', type: 'object', model: typeName, http: {source: 'body'},
description: 'An object of Change property name/value pairs',
},
],
returns: { arg: 'result', type: this.Change.modelName, root: true },
http: { verb: 'put', path: '/:id/changes/last' },
returns: {arg: 'result', type: this.Change.modelName, root: true},
http: {verb: 'put', path: '/:id/changes/last'},
});
}
@ -957,8 +956,8 @@ module.exports = function(registry) {
description: 'Create a change stream.',
accessType: 'READ',
http: [
{ verb: 'post', path: '/change-stream' },
{ verb: 'get', path: '/change-stream' },
{verb: 'post', path: '/change-stream'},
{verb: 'get', path: '/change-stream'},
],
accepts: {
arg: 'options',
@ -1021,8 +1020,8 @@ module.exports = function(registry) {
filter.fields[idName] = true;
// TODO(ritch) this whole thing could be optimized a bit more
Change.find({ where: {
checkpoint: { gte: since },
Change.find({where: {
checkpoint: {gte: since},
modelName: this.modelName,
}}, function(err, changes) {
if (err) return callback(err);
@ -1030,7 +1029,7 @@ module.exports = function(registry) {
var ids = changes.map(function(change) {
return change.getModelId();
});
filter.where[idName] = { inq: ids };
filter.where[idName] = {inq: ids};
model.find(filter, function(err, models) {
if (err) return callback(err);
var modelIds = models.map(function(m) {
@ -1097,7 +1096,7 @@ module.exports = function(registry) {
}
if (typeof since !== 'object') {
since = { source: since, target: since };
since = {source: since, target: since};
}
if (typeof options === 'function') {
@ -1268,7 +1267,7 @@ module.exports = function(registry) {
}
if (callback) {
var newCheckpoints = { source: newSourceCp, target: newTargetCp };
var newCheckpoints = {source: newSourceCp, target: newTargetCp};
callback(null, conflicts, newCheckpoints, updates);
}
}
@ -1291,7 +1290,7 @@ module.exports = function(registry) {
deltas.forEach(function(change) {
change = new Change(change);
var type = change.type();
var update = { type: type, change: change };
var update = {type: type, change: change};
switch (type) {
case Change.CREATE:
case Change.UPDATE:
@ -1383,7 +1382,7 @@ module.exports = function(registry) {
if (conflicts.length) {
err = new Error(g.f('Conflict'));
err.statusCode = 409;
err.details = { conflicts: conflicts };
err.details = {conflicts: conflicts};
return callback(err);
}
callback();
@ -1395,8 +1394,8 @@ module.exports = function(registry) {
var idName = Model.dataSource.idName(Model.modelName);
var affectedIds = updates.map(function(u) { return u.change.modelId; });
var whereAffected = {};
whereAffected[idName] = { inq: affectedIds };
Model.find({ where: whereAffected }, function(err, affectedList) {
whereAffected[idName] = {inq: affectedIds};
Model.find({where: whereAffected}, function(err, affectedList) {
if (err) return callback(err);
var dataLookup = {};
affectedList.forEach(function(it) {
@ -1742,7 +1741,7 @@ module.exports = function(registry) {
PersistedModel.findLastChange = function(id, cb) {
var Change = this.getChangeModel();
Change.findOne({ where: { modelId: id }}, cb);
Change.findOne({where: {modelId: id}}, cb);
};
PersistedModel.updateLastChange = function(id, data, cb) {
@ -1778,7 +1777,7 @@ module.exports = function(registry) {
var idName = this.getIdName();
var Model = this;
var changes = new PassThrough({ objectMode: true });
var changes = new PassThrough({objectMode: true});
var writeable = true;
changes.destroy = function() {

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('./globalize');
var assert = require('assert');
var extend = require('util')._extend;

View File

@ -9,6 +9,7 @@
* @private
*/
'use strict';
var runtime = exports;
/**

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('./globalize');
var assert = require('assert');
var express = require('express');
@ -11,7 +12,7 @@ var mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists;
var debug = require('debug')('loopback:app');
var stableSortInPlace = require('stable').inplace;
var BUILTIN_MIDDLEWARE = { builtin: true };
var BUILTIN_MIDDLEWARE = {builtin: true};
var proto = {};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
exports.createPromiseCallback = createPromiseCallback;
var Promise = require('bluebird');

View File

@ -67,7 +67,7 @@
"chai": "^3.5.0",
"cookie-parser": "^1.3.4",
"es5-shim": "^4.1.0",
"eslint-config-loopback": "^1.0.0",
"eslint-config-loopback": "^5.0.0",
"express-session": "^1.14.0",
"grunt": "^1.0.1",
"grunt-browserify": "^5.0.0",

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var g = require('../../lib/globalize');
module.exports = function() {

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(options) {
throw new Error('loopback.errorHandler is no longer available.' +
' Please use the module "strong-error-handler" instead.');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var favicon = require('serve-favicon');
var path = require('path');

View File

@ -7,6 +7,7 @@
* Module dependencies.
*/
'use strict';
var g = require('../../lib/globalize');
var loopback = require('../../lib/loopback');
var async = require('async');
@ -49,7 +50,7 @@ function rest() {
if (app.isAuthEnabled) {
var AccessToken = registry.getModelByType('AccessToken');
handlers.push(loopback.token({ model: AccessToken, app: app }));
handlers.push(loopback.token({model: AccessToken, app: app}));
}
handlers.push(function(req, res, next) {

View File

@ -13,4 +13,5 @@
* for the full list of available options.
* @header loopback.static(root, [options])
*/
'use strict';
module.exports = require('express').static;

View File

@ -7,6 +7,7 @@
* Export the middleware.
*/
'use strict';
module.exports = status;
/**

View File

@ -7,6 +7,7 @@
* Module dependencies.
*/
'use strict';
var loopback = require('../../lib/loopback');
var assert = require('assert');
var debug = require('debug')('loopback:middleware:token');

View File

@ -8,6 +8,7 @@
* See discussion in Connect pull request #954 for more details
* https://github.com/senchalabs/connect/pull/954.
*/
'use strict';
module.exports = urlNotFound;
/**

View File

@ -3,14 +3,15 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../');
var lt = require('./helpers/loopback-testing-helper');
var path = require('path');
var ACCESS_CONTROL_APP = path.join(__dirname, 'fixtures', 'access-control');
var app = require(path.join(ACCESS_CONTROL_APP, 'server/server.js'));
var assert = require('assert');
var USER = { email: 'test@test.test', password: 'test' };
var CURRENT_USER = { email: 'current@test.test', password: 'test' };
var USER = {email: 'test@test.test', password: 'test'};
var CURRENT_USER = {email: 'current@test.test', password: 'test'};
var debug = require('debug')('loopback:test:access-control.integration');
describe('access control - integration', function() {
@ -146,7 +147,7 @@ describe('access control - integration', function() {
});
describe('/banks', function() {
var SPECIAL_USER = { email: 'special@test.test', password: 'test' };
var SPECIAL_USER = {email: 'special@test.test', password: 'test'};
// define dynamic role that would only grant access when the authenticated user's email is equal to
// SPECIAL_USER's email

View File

@ -3,15 +3,20 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var expect = require('chai').expect;
var cookieParser = require('cookie-parser');
var LoopBackContext = require('loopback-context');
var contextMiddleware = require('loopback-context').perRequest;
var loopback = require('../');
var extend = require('util')._extend;
var session = require('express-session');
var request = require('supertest');
var app = loopback();
var Token = loopback.AccessToken.extend('MyToken');
var ds = loopback.createDataSource({ connector: loopback.Memory });
var ds = loopback.createDataSource({connector: loopback.Memory});
Token.attachTo(ds);
var ACL = loopback.ACL;
@ -50,7 +55,7 @@ describe('loopback.token(options)', function() {
var tokenId = this.token.id;
var app = createTestApp(
this.token,
{ token: { searchDefaultTokenKeys: false }},
{token: {searchDefaultTokenKeys: false}},
done);
var agent = request.agent(app);
@ -158,7 +163,7 @@ describe('loopback.token(options)', function() {
.set('authorization', id)
.end(function(err, res) {
assert(!err);
assert.deepEqual(res.body, { userId: userId });
assert.deepEqual(res.body, {userId: userId});
done();
});
@ -174,7 +179,7 @@ describe('loopback.token(options)', function() {
.set('authorization', id)
.end(function(err, res) {
assert(!err);
assert.deepEqual(res.body, { userId: userId, state: 1 });
assert.deepEqual(res.body, {userId: userId, state: 1});
done();
});
@ -190,20 +195,20 @@ describe('loopback.token(options)', function() {
.set('authorization', id)
.end(function(err, res) {
assert(!err);
assert.deepEqual(res.body, { userId: userId, state: 1 });
assert.deepEqual(res.body, {userId: userId, state: 1});
done();
});
});
it('should skip when req.token is already present', function(done) {
var tokenStub = { id: 'stub id' };
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
next();
});
app.use(loopback.token({ model: Token }));
app.use(loopback.token({model: Token}));
app.get('/', function(req, res, next) {
res.send(req.accessToken);
});
@ -223,13 +228,13 @@ describe('loopback.token(options)', function() {
describe('loading multiple instances of token middleware', function() {
it('should skip when req.token is already present and no further options are set',
function(done) {
var tokenStub = { id: 'stub id' };
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
next();
});
app.use(loopback.token({ model: Token }));
app.use(loopback.token({model: Token}));
app.get('/', function(req, res, next) {
res.send(req.accessToken);
});
@ -249,7 +254,7 @@ describe('loopback.token(options)', function() {
it('should not overwrite valid existing token (has "id" property) ' +
' when overwriteExistingToken is falsy',
function(done) {
var tokenStub = { id: 'stub id' };
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
@ -279,7 +284,7 @@ describe('loopback.token(options)', function() {
' when enableDoubkecheck is true',
function(done) {
var token = this.token;
var app = loopback();
app.use(function(req, res, next) {
req.accessToken = null;
next();
@ -313,8 +318,8 @@ describe('loopback.token(options)', function() {
'and overwriteExistingToken options are truthy',
function(done) {
var token = this.token;
var tokenStub = { id: 'stub id' };
var tokenStub = {id: 'stub id'};
var app = loopback();
app.use(function(req, res, next) {
req.accessToken = tokenStub;
@ -385,7 +390,7 @@ describe('AccessToken', function() {
// Overwrite User settings - enable eternal tokens
Token.app.models.User.settings.allowEternalTokens = true;
Token.create({ userId: '123', ttl: -1 }, function(err, token) {
Token.create({userId: '123', ttl: -1}, function(err, token) {
if (err) return done(err);
token.validate(function(err, isValid) {
if (err) return done(err);
@ -402,7 +407,7 @@ describe('AccessToken', function() {
it('supports two-arg variant with no options', function(done) {
var expectedTokenId = this.token.id;
var req = mockRequest({
headers: { 'authorization': expectedTokenId },
headers: {'authorization': expectedTokenId},
});
Token.findForRequest(req, function(err, token) {
@ -435,7 +440,7 @@ describe('app.enableAuth()', function() {
var app;
beforeEach(function setupAuthWithModels() {
app = loopback();
app.enableAuth({ dataSource: ds });
app.enableAuth({dataSource: ds});
});
beforeEach(createTestingToken);
@ -458,7 +463,7 @@ describe('app.enableAuth()', function() {
});
it('prevent remote call with app setting status on denied ACL', function(done) {
createTestAppAndRequest(this.token, { app: { aclErrorStatus: 403 }}, done)
createTestAppAndRequest(this.token, {app: {aclErrorStatus: 403}}, done)
.del('/tests/123')
.expect(403)
.set('authorization', this.token.id)
@ -476,7 +481,7 @@ describe('app.enableAuth()', function() {
});
it('prevent remote call with app setting status on denied ACL', function(done) {
createTestAppAndRequest(this.token, { model: { aclErrorStatus: 404 }}, done)
createTestAppAndRequest(this.token, {model: {aclErrorStatus: 404}}, done)
.del('/tests/123')
.expect(404)
.set('authorization', this.token.id)
@ -512,22 +517,22 @@ describe('app.enableAuth()', function() {
});
it('stores token in the context', function(done) {
var TestModel = loopback.createModel('TestModel', { base: 'Model' });
var TestModel = loopback.createModel('TestModel', {base: 'Model'});
TestModel.getToken = function(cb) {
var ctx = LoopBackContext.getCurrentContext();
cb(null, ctx && ctx.get('accessToken') || null);
};
TestModel.remoteMethod('getToken', {
returns: { arg: 'token', type: 'object' },
http: { verb: 'GET', path: '/token' },
returns: {arg: 'token', type: 'object'},
http: {verb: 'GET', path: '/token'},
});
var app = loopback();
app.model(TestModel, { dataSource: null });
app.model(TestModel, {dataSource: null});
app.enableAuth();
app.use(contextMiddleware());
app.use(loopback.token({ model: Token }));
app.use(loopback.token({model: Token}));
app.use(loopback.rest());
var token = this.token;
@ -556,7 +561,7 @@ describe('app.enableAuth()', function() {
saveUninitialized: true,
resave: true,
}));
app.use(loopback.token({ model: Token }));
app.use(loopback.token({model: Token}));
app.get('/', function(req, res) { res.send('OK'); });
app.use(loopback.rest());
@ -572,7 +577,7 @@ describe('app.enableAuth()', function() {
function createTestingToken(done) {
var test = this;
Token.create({ userId: '123' }, function(err, token) {
Token.create({userId: '123'}, function(err, token) {
if (err) return done(err);
test.token = token;
@ -602,10 +607,10 @@ function createTestApp(testToken, settings, done) {
app.use(cookieParser('secret'));
app.use(loopback.token(tokenSettings));
app.set('remoting', { errorHandler: { debug: true, log: false }});
app.set('remoting', {errorHandler: {debug: true, log: false}});
app.get('/token', function(req, res) {
res.cookie('authorization', testToken.id, { signed: true });
res.cookie('access_token', testToken.id, { signed: true });
res.cookie('authorization', testToken.id, {signed: true});
res.cookie('access_token', testToken.id, {signed: true});
res.end();
});
app.get('/', function(req, res) {
@ -621,7 +626,7 @@ function createTestApp(testToken, settings, done) {
res.status(req.accessToken ? 200 : 401).end();
});
app.use('/users/:uid', function(req, res) {
var result = { userId: req.params.uid };
var result = {userId: req.params.uid};
if (req.query.state) {
result.state = req.query.state;
} else if (req.url !== '/') {
@ -661,14 +666,14 @@ function createTestApp(testToken, settings, done) {
}
function givenLocalTokenModel() {
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
app.dataSource('db', { connector: 'memory' });
var app = loopback({localRegistry: true, loadBuiltinModels: true});
app.dataSource('db', {connector: 'memory'});
var User = app.registry.getModel('User');
app.model(User, { dataSource: 'db' });
app.model(User, {dataSource: 'db'});
var Token = app.registry.getModel('AccessToken');
app.model(Token, { dataSource: 'db' });
app.model(Token, {dataSource: 'db'});
return Token;
}

View File

@ -3,15 +3,20 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('../index');
var Scope = loopback.Scope;
var ACL = loopback.ACL;
var request = require('supertest');
var Role = loopback.Role;
var RoleMapping = loopback.RoleMapping;
var User = loopback.User;
var testModel;
// Speed up the password hashing algorithm for tests
User.settings.saltWorkFactor = 4;
function checkResult(err, result) {
// console.log(err, result);
assert(!err);
@ -19,12 +24,12 @@ function checkResult(err, result) {
var ds = null;
before(function() {
ds = loopback.createDataSource({ connector: loopback.Memory });
ds = loopback.createDataSource({connector: loopback.Memory});
});
describe('security scopes', function() {
beforeEach(function() {
var ds = this.ds = loopback.createDataSource({ connector: loopback.Memory });
var ds = this.ds = loopback.createDataSource({connector: loopback.Memory});
testModel = loopback.PersistedModel.extend('testModel');
ACL.attachTo(ds);
Role.attachTo(ds);
@ -35,7 +40,7 @@ describe('security scopes', function() {
});
it('should allow access to models for the given scope by wildcard', function() {
Scope.create({ name: 'userScope', description: 'access user information' },
Scope.create({name: 'userScope', description: 'access user information'},
function(err, scope) {
ACL.create({
principalType: ACL.SCOPE, principalId: scope.id,
@ -50,14 +55,14 @@ describe('security scopes', function() {
});
it('should allow access to models for the given scope', function() {
Scope.create({ name: 'testModelScope', description: 'access testModel information' },
Scope.create({name: 'testModelScope', description: 'access testModel information'},
function(err, scope) {
ACL.create({
principalType: ACL.SCOPE, principalId: scope.id,
model: 'testModel', property: 'name',
accessType: ACL.READ, permission: ACL.ALLOW,
}, function(err, resource) {
ACL.create({ principalType: ACL.SCOPE, principalId: scope.id,
ACL.create({principalType: ACL.SCOPE, principalId: scope.id,
model: 'testModel', property: 'name',
accessType: ACL.WRITE, permission: ACL.DENY,
}, function(err, resource) {
@ -117,11 +122,11 @@ describe('security ACLs', function() {
acls = acls.map(function(a) { return new ACL(a); });
var perm = ACL.resolvePermission(acls, req);
assert.deepEqual(perm, { model: 'account',
assert.deepEqual(perm, {model: 'account',
property: 'find',
accessType: 'WRITE',
permission: 'ALLOW',
methodNames: [] });
methodNames: []});
});
it('should allow access to models for the given principal by wildcard', function() {
@ -197,16 +202,16 @@ describe('security ACLs', function() {
name: {
type: String,
acls: [
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.WRITE, permission: ACL.DENY },
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW},
],
},
}, {
acls: [
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW},
],
});
@ -231,20 +236,20 @@ describe('security ACLs', function() {
name: {
type: String,
acls: [
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.WRITE, permission: ACL.DENY },
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW},
],
},
}, {
acls: [
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW },
{ principalType: ACL.USER, principalId: 'u002',
accessType: ACL.EXECUTE, permission: ACL.ALLOW },
{ principalType: ACL.USER, principalId: 'u003',
accessType: ACL.EXECUTE, permission: ACL.DENY },
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW},
{principalType: ACL.USER, principalId: 'u002',
accessType: ACL.EXECUTE, permission: ACL.ALLOW},
{principalType: ACL.USER, principalId: 'u003',
accessType: ACL.EXECUTE, permission: ACL.DENY},
],
});
@ -285,20 +290,20 @@ describe('security ACLs', function() {
name: {
type: String,
acls: [
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.WRITE, permission: ACL.DENY },
{ principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW},
],
},
}, {
acls: [
{ principalType: ACL.USER, principalId: 'u001', property: 'name',
accessType: ACL.ALL, permission: ACL.ALLOW },
{ principalType: ACL.USER, principalId: 'u002', property: 'findOne',
accessType: ACL.ALL, permission: ACL.ALLOW },
{ principalType: ACL.USER, principalId: 'u003', property: ['findOne', 'findById'],
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: 'u001', property: 'name',
accessType: ACL.ALL, permission: ACL.ALLOW},
{principalType: ACL.USER, principalId: 'u002', property: 'findOne',
accessType: ACL.ALL, permission: ACL.ALLOW},
{principalType: ACL.USER, principalId: 'u003', property: ['findOne', 'findById'],
accessType: ACL.ALL, permission: ACL.ALLOW},
],
});
@ -318,7 +323,7 @@ describe('security ACLs', function() {
var log = function() {};
// Create
User.create({ name: 'Raymond', email: 'x@y.com', password: 'foobar' }, function(err, user) {
User.create({name: 'Raymond', email: 'x@y.com', password: 'foobar'}, function(err, user) {
log('User: ', user.toObject());
var userId = user.id;
@ -328,16 +333,16 @@ describe('security ACLs', function() {
name: {
type: String,
acls: [
{ principalType: ACL.USER, principalId: userId,
accessType: ACL.WRITE, permission: ACL.DENY },
{ principalType: ACL.USER, principalId: userId,
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: userId,
accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: userId,
accessType: ACL.ALL, permission: ACL.ALLOW},
],
},
}, {
acls: [
{ principalType: ACL.USER, principalId: userId,
accessType: ACL.ALL, permission: ACL.ALLOW },
{principalType: ACL.USER, principalId: userId,
accessType: ACL.ALL, permission: ACL.ALLOW},
],
defaultPermission: 'DENY',
});
@ -349,10 +354,10 @@ describe('security ACLs', function() {
}, function(err, acl) {
log('ACL 1: ', acl.toObject());
Role.create({ name: 'MyRole' }, function(err, myRole) {
Role.create({name: 'MyRole'}, function(err, myRole) {
log('Role: ', myRole.toObject());
myRole.principals.create({ principalType: RoleMapping.USER, principalId: userId },
myRole.principals.create({principalType: RoleMapping.USER, principalId: userId},
function(err, p) {
log('Principal added to role: ', p.toObject());
@ -365,7 +370,7 @@ describe('security ACLs', function() {
ACL.checkAccessForContext({
principals: [
{ type: ACL.USER, id: userId },
{type: ACL.USER, id: userId},
],
model: 'Customer',
property: 'name',
@ -376,7 +381,7 @@ describe('security ACLs', function() {
ACL.checkAccessForContext({
principals: [
{ type: ACL.ROLE, id: Role.EVERYONE },
{type: ACL.ROLE, id: Role.EVERYONE},
],
model: 'Customer',
property: 'name',
@ -400,10 +405,10 @@ describe('access check', function() {
var beforeHookCalled = false;
app.use(loopback.rest());
app.set('remoting', { errorHandler: { debug: true, log: false }});
app.set('remoting', {errorHandler: {debug: true, log: false}});
app.enableAuth();
app.dataSource('test', { connector: 'memory' });
app.model(MyTestModel, { dataSource: 'test' });
app.dataSource('test', {connector: 'memory'});
app.model(MyTestModel, {dataSource: 'test'});
// fake / spy on the checkAccess method
MyTestModel.checkAccess = function() {

View File

@ -3,6 +3,8 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var async = require('async');
var path = require('path');
@ -14,6 +16,7 @@ var PersistedModel = loopback.PersistedModel;
var describe = require('./util/describe');
var expect = require('chai').expect;
var it = require('./util/it');
var request = require('supertest');
describe('app', function() {
var app;
@ -309,7 +312,7 @@ describe('app', function() {
it('sets req.baseUrl and req.originalUrl', function(done) {
var reqProps;
app.middleware('initial', function(req, res, next) {
reqProps = { baseUrl: req.baseUrl, originalUrl: req.originalUrl };
reqProps = {baseUrl: req.baseUrl, originalUrl: req.originalUrl};
next();
});
@ -317,7 +320,7 @@ describe('app', function() {
executeMiddlewareHandlers(app, '/test/url', function(err) {
if (err) return done(err);
expect(reqProps).to.eql({ baseUrl: '', originalUrl: '/test/url' });
expect(reqProps).to.eql({baseUrl: '', originalUrl: '/test/url'});
done();
});
@ -451,7 +454,7 @@ describe('app', function() {
describe.onServer('.middlewareFromConfig', function() {
it('provides API for loading middleware from JSON config', function(done) {
var steps = [];
var expectedConfig = { key: 'value' };
var expectedConfig = {key: 'value'};
var handlerFactory = function() {
var args = Array.prototype.slice.apply(arguments);
@ -495,7 +498,7 @@ describe('app', function() {
enabled: true,
phase: 'routes:before',
methods: ['get', 'head'],
params: { x: 1 },
params: {x: 1},
});
// This should be skipped as the verb doesn't match
@ -503,7 +506,7 @@ describe('app', function() {
enabled: true,
phase: 'routes:before',
methods: ['post'],
params: { x: 2 },
params: {x: 2},
});
executeMiddlewareHandlers(app, function(err) {
@ -513,7 +516,7 @@ describe('app', function() {
['before'],
[expectedConfig],
['after', 2],
[{ x: 1 }],
[{x: 1}],
]);
done();
@ -618,13 +621,13 @@ describe('app', function() {
var app, db, MyTestModel;
beforeEach(function() {
app = loopback();
app.set('remoting', { errorHandler: { debug: true, log: false }});
db = loopback.createDataSource({ connector: loopback.Memory });
app.set('remoting', {errorHandler: {debug: true, log: false}});
db = loopback.createDataSource({connector: loopback.Memory});
MyTestModel = app.registry.createModel('MyTestModel');
});
it('Expose a `Model` to remote clients', function() {
var Color = PersistedModel.extend('color', { name: String });
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
@ -632,14 +635,14 @@ describe('app', function() {
});
it('uses singular name as app.remoteObjects() key', function() {
var Color = PersistedModel.extend('color', { name: String });
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
expect(app.remoteObjects()).to.eql({ color: Color });
expect(app.remoteObjects()).to.eql({color: Color});
});
it('uses singular name as shared class name', function() {
var Color = PersistedModel.extend('color', { name: String });
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
var classes = app.remotes().classes().map(function(c) { return c.name; });
@ -647,7 +650,7 @@ describe('app', function() {
});
it('registers existing models to app.models', function() {
var Color = db.createModel('color', { name: String });
var Color = db.createModel('color', {name: String});
app.model(Color);
expect(Color.app).to.be.equal(app);
expect(Color.shared).to.equal(true);
@ -656,7 +659,7 @@ describe('app', function() {
});
it('emits a `modelRemoted` event', function() {
var Color = PersistedModel.extend('color', { name: String });
var Color = PersistedModel.extend('color', {name: String});
Color.shared = true;
var remotedClass;
app.on('modelRemoted', function(sharedClass) {
@ -668,7 +671,7 @@ describe('app', function() {
});
it('emits a `remoteMethodDisabled` event', function() {
var Color = PersistedModel.extend('color', { name: String });
var Color = PersistedModel.extend('color', {name: String});
Color.shared = true;
var remoteMethodDisabledClass, disabledRemoteMethod;
app.on('remoteMethodDisabled', function(sharedClass, methodName) {
@ -687,7 +690,7 @@ describe('app', function() {
app.use(loopback.rest());
request(app).get('/colors').expect(404, function(err, res) {
if (err) return done(err);
var Color = PersistedModel.extend('color', { name: String });
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
request(app).get('/colors').expect(200, done);
@ -695,13 +698,13 @@ describe('app', function() {
});
it('accepts null dataSource', function(done) {
app.model(MyTestModel, { dataSource: null });
app.model(MyTestModel, {dataSource: null});
expect(MyTestModel.dataSource).to.eql(null);
done();
});
it('accepts false dataSource', function(done) {
app.model(MyTestModel, { dataSource: false });
app.model(MyTestModel, {dataSource: false});
expect(MyTestModel.getDataSource()).to.eql(null);
done();
});
@ -720,7 +723,7 @@ describe('app', function() {
describe('app.model(ModelCtor, config)', function() {
it('attaches the model to a datasource', function() {
var previousModel = loopback.registry.findModel('TestModel');
app.dataSource('db', { connector: 'memory' });
app.dataSource('db', {connector: 'memory'});
if (previousModel) {
delete previousModel.dataSource;
@ -728,16 +731,16 @@ describe('app', function() {
assert(!previousModel || !previousModel.dataSource);
var TestModel = app.registry.createModel('TestModel');
app.model(TestModel, { dataSource: 'db' });
app.model(TestModel, {dataSource: 'db'});
expect(app.models.TestModel.dataSource).to.equal(app.dataSources.db);
});
});
describe('app.models', function() {
it('is unique per app instance', function() {
app.dataSource('db', { connector: 'memory' });
app.dataSource('db', {connector: 'memory'});
var Color = app.registry.createModel('Color');
app.model(Color, { dataSource: 'db' });
app.model(Color, {dataSource: 'db'});
expect(app.models.Color).to.equal(Color);
var anotherApp = loopback();
expect(anotherApp.models.Color).to.equal(undefined);
@ -746,7 +749,7 @@ describe('app', function() {
describe('app.dataSources', function() {
it('is unique per app instance', function() {
app.dataSource('ds', { connector: 'memory' });
app.dataSource('ds', {connector: 'memory'});
expect(app.datasources.ds).to.not.equal(undefined);
var anotherApp = loopback();
expect(anotherApp.datasources.ds).to.equal(undefined);
@ -756,7 +759,7 @@ describe('app', function() {
describe('app.dataSource', function() {
it('looks up the connector in `app.connectors`', function() {
app.connector('custom', loopback.Memory);
app.dataSource('custom', { connector: 'custom' });
app.dataSource('custom', {connector: 'custom'});
expect(app.dataSources.custom.name).to.equal(loopback.Memory.name);
});
@ -766,12 +769,12 @@ describe('app', function() {
});
expect(function() {
app.dataSource('bad-ds', { connector: 'throwing' });
app.dataSource('bad-ds', {connector: 'throwing'});
}).to.throw(/bad-ds.*throwing/);
});
it('adds app reference to the data source object', function() {
app.dataSource('ds', { connector: 'memory' });
app.dataSource('ds', {connector: 'memory'});
expect(app.datasources.ds.app).to.not.equal(undefined);
expect(app.datasources.ds.app).to.equal(app);
});
@ -864,11 +867,11 @@ describe('app', function() {
it('auto-configures required models to provided dataSource', function() {
var AUTH_MODELS = ['User', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
var app = loopback({localRegistry: true, loadBuiltinModels: true});
require('../lib/builtin-models')(app.registry);
var db = app.dataSource('db', { connector: 'memory' });
var db = app.dataSource('db', {connector: 'memory'});
app.enableAuth({ dataSource: 'db' });
app.enableAuth({dataSource: 'db'});
expect(Object.keys(app.models)).to.include.members(AUTH_MODELS);
@ -880,12 +883,12 @@ describe('app', function() {
});
it('detects already configured subclass of a required model', function() {
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
var db = app.dataSource('db', { connector: 'memory' });
var Customer = app.registry.createModel('Customer', {}, { base: 'User' });
app.model(Customer, { dataSource: 'db' });
var app = loopback({localRegistry: true, loadBuiltinModels: true});
var db = app.dataSource('db', {connector: 'memory'});
var Customer = app.registry.createModel('Customer', {}, {base: 'User'});
app.model(Customer, {dataSource: 'db'});
app.enableAuth({ dataSource: 'db' });
app.enableAuth({dataSource: 'db'});
expect(Object.keys(app.models)).to.not.include('User');
});
@ -980,15 +983,15 @@ describe('app', function() {
var app, db;
beforeEach(function() {
app = loopback();
db = loopback.createDataSource({ connector: loopback.Memory });
db = loopback.createDataSource({connector: loopback.Memory});
});
it.onServer('normalizes the http path', function(done) {
var UserAccount = PersistedModel.extend(
'UserAccount',
{ name: String },
{name: String},
{
remoting: { normalizeHttpPath: true },
remoting: {normalizeHttpPath: true},
});
app.model(UserAccount);
UserAccount.attachTo(db);

View File

@ -3,12 +3,16 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var expect = require('chai').expect;
var loopback = require('../');
describe('PersistedModel.createChangeStream()', function() {
describe('configured to source changes locally', function() {
before(function() {
var test = this;
var app = loopback({ localRegistry: true });
var ds = app.dataSource('ds', { connector: 'memory' });
var app = loopback({localRegistry: true});
var ds = app.dataSource('ds', {connector: 'memory'});
var Score = app.registry.createModel('Score');
this.Score = app.model(Score, {
dataSource: 'ds',
@ -27,13 +31,13 @@ describe('PersistedModel.createChangeStream()', function() {
done();
});
Score.create({ team: 'foo' });
Score.create({team: 'foo'});
});
});
it('should detect update', function(done) {
var Score = this.Score;
Score.create({ team: 'foo' }, function(err, newScore) {
Score.create({team: 'foo'}, function(err, newScore) {
Score.createChangeStream(function(err, changes) {
changes.on('data', function(change) {
expect(change.type).to.equal('update');
@ -50,7 +54,7 @@ describe('PersistedModel.createChangeStream()', function() {
it('should detect delete', function(done) {
var Score = this.Score;
Score.create({ team: 'foo' }, function(err, newScore) {
Score.create({team: 'foo'}, function(err, newScore) {
Score.createChangeStream(function(err, changes) {
changes.on('data', function(change) {
expect(change.type).to.equal('remove');
@ -69,8 +73,8 @@ describe('PersistedModel.createChangeStream()', function() {
describe.skip('configured to source changes using pubsub', function() {
before(function() {
var test = this;
var app = loopback({ localRegistry: true });
var db = app.dataSource('ds', { connector: 'memory' });
var app = loopback({localRegistry: true});
var db = app.dataSource('ds', {connector: 'memory'});
var ps = app.dataSource('ps', {
host: 'localhost',
port: '12345',

View File

@ -3,8 +3,11 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var async = require('async');
var expect = require('chai').expect;
var loopback = require('../');
var Change, TestModel;
@ -15,7 +18,7 @@ describe('Change', function() {
});
TestModel = loopback.PersistedModel.extend('ChangeTestModel',
{
id: { id: true, type: 'string', defaultFn: 'guid' },
id: {id: true, type: 'string', defaultFn: 'guid'},
},
{
trackChanges: true,
@ -475,20 +478,20 @@ describe('Change', function() {
describe('Change.diff(modelName, since, remoteChanges, callback)', function() {
beforeEach(function(done) {
Change.create([
{ rev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1 },
{ rev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1 },
{ rev: 'bat', modelName: this.modelName, modelId: 11, checkpoint: 1 },
{rev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
{rev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1},
{rev: 'bat', modelName: this.modelName, modelId: 11, checkpoint: 1},
], done);
});
it('should return delta and conflict lists', function(done) {
var remoteChanges = [
// an update => should result in a delta
{ rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1 },
{rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
// no change => should not result in a delta / conflict
{ rev: 'bar', prev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1 },
{rev: 'bar', prev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1},
// a conflict => should result in a conflict
{ rev: 'bat2', prev: 'bat0', modelName: this.modelName, modelId: 11, checkpoint: 1 },
{rev: 'bat2', prev: 'bat0', modelName: this.modelName, modelId: 11, checkpoint: 1},
];
Change.diff(this.modelName, 0, remoteChanges, function(err, diff) {
@ -504,11 +507,11 @@ describe('Change', function() {
it('should return delta and conflict lists - promise variant', function(done) {
var remoteChanges = [
// an update => should result in a delta
{ rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1 },
{rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
// no change => should not result in a delta / conflict
{ rev: 'bar', prev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1 },
{rev: 'bar', prev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1},
// a conflict => should result in a conflict
{ rev: 'bat2', prev: 'bat0', modelName: this.modelName, modelId: 11, checkpoint: 1 },
{rev: 'bat2', prev: 'bat0', modelName: this.modelName, modelId: 11, checkpoint: 1},
];
Change.diff(this.modelName, 0, remoteChanges)

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var async = require('async');
var loopback = require('../');
var expect = require('chai').expect;

View File

@ -3,6 +3,10 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('../');
describe('DataSource', function() {
var memory;
@ -16,7 +20,7 @@ describe('DataSource', function() {
describe('dataSource.createModel(name, properties, settings)', function() {
it('Define a model and attach it to a `DataSource`', function() {
var Color = memory.createModel('color', { name: String });
var Color = memory.createModel('color', {name: String});
assert.isFunc(Color, 'find');
assert.isFunc(Color, 'findById');
assert.isFunc(Color, 'findOne');
@ -42,13 +46,13 @@ describe('DataSource', function() {
it('should honor settings.base', function() {
var Base = memory.createModel('base');
var Color = memory.createModel('color', { name: String }, { base: Base });
var Color = memory.createModel('color', {name: String}, {base: Base});
assert(Color.prototype instanceof Base);
assert.equal(Color.base, Base);
});
it('should use loopback.PersistedModel as the base for DBs', function() {
var Color = memory.createModel('color', { name: String });
var Color = memory.createModel('color', {name: String});
assert(Color.prototype instanceof loopback.PersistedModel);
assert.equal(Color.base, loopback.PersistedModel);
});
@ -65,7 +69,7 @@ describe('DataSource', function() {
connector: new Connector(),
});
var Color = ds.createModel('color', { name: String });
var Color = ds.createModel('color', {name: String});
assert(Color.prototype instanceof Color.registry.getModel('Model'));
assert.equal(Color.base.modelName, 'PersistedModel');
});
@ -116,3 +120,19 @@ describe('DataSource', function() {
});
});
});
var assertValidDataSource = function(dataSource) {
// has methods
assert.isFunc(dataSource, 'createModel');
assert.isFunc(dataSource, 'discoverModelDefinitions');
assert.isFunc(dataSource, 'discoverSchema');
assert.isFunc(dataSource, 'enableRemote');
assert.isFunc(dataSource, 'disableRemote');
assert.isFunc(dataSource, 'defineOperation');
assert.isFunc(dataSource, 'operations');
};
assert.isFunc = function(obj, name) {
assert(obj, 'cannot assert function ' + name + ' on object that doesnt exist');
assert(typeof obj[name] === 'function', name + ' is not a function');
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var path = require('path');
var loopback = require('../../');
var models = require('../fixtures/e2e/models');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var path = require('path');
var loopback = require('../../');
var models = require('../fixtures/e2e/models');
@ -33,7 +34,7 @@ describe('Replication', function() {
LocalTestModel.replicate(0, TestModel, function() {
if (err) return done(err);
TestModel.findOne({ n: RANDOM }, function(err, found) {
TestModel.findOne({n: RANDOM}, function(err, found) {
assert.equal(created.id, found.id);
done();

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../');
var MyEmail;
var assert = require('assert');
@ -10,37 +11,37 @@ 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' },
] });
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' },
] });
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' },
] });
var connector = new MailConnector({transports: [
{type: 'stub', service: 'gmail'},
]});
assert(connector.transportForName('stub'));
});
it('should set up a single transport for SMTP', function() {
var connector = new MailConnector({ transport:
{ type: 'smtp', service: 'gmail' },
var connector = new MailConnector({transport:
{type: 'smtp', service: 'gmail'},
});
assert(connector.transportForName('smtp'));
});
it('should set up a aliased transport for SMTP', function() {
var connector = new MailConnector({ transport:
{ type: 'smtp', service: 'ses-us-east-1', alias: 'ses-smtp' },
var connector = new MailConnector({transport:
{type: 'smtp', service: 'ses-us-east-1', alias: 'ses-smtp'},
});
assert(connector.transportForName('ses-smtp'));
@ -52,7 +53,7 @@ describe('Email and SMTP', function() {
MyEmail = loopback.Email.extend('my-email');
var ds = loopback.createDataSource('email', {
connector: loopback.Mail,
transports: [{ type: 'STUB' }],
transports: [{type: 'STUB'}],
});
MyEmail.attachTo(ds);
});

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../');
var app;
var assert = require('assert');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../../..');
var boot = require('loopback-boot');
var app = module.exports = loopback({
@ -14,7 +15,7 @@ var errorHandler = require('strong-error-handler');
boot(app, __dirname);
var apiPath = '/api';
app.use(loopback.token({ model: app.models.accessToken }));
app.use(loopback.token({model: app.models.accessToken}));
app.use(apiPath, loopback.rest());
app.use(loopback.urlNotFound());

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../../../index');
var PersistedModel = loopback.PersistedModel;

View File

@ -3,8 +3,9 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../../../index');
var app = module.exports = loopback({ localRegistry: true });
var app = module.exports = loopback({localRegistry: true});
var models = require('./models');
var TestModel = models.TestModel;

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Todo) {
};

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var boot = require('loopback-boot');
var loopback = require('../../../../../index');

View File

@ -3,4 +3,5 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
process.loadedFooJS = true;

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
module.exports = function(Bar) {
process.loadedBarJS = true;
};

View File

@ -3,9 +3,10 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../../../index');
var boot = require('loopback-boot');
var app = module.exports = loopback({ localRegistry: true });
var app = module.exports = loopback({localRegistry: true});
var errorHandler = require('strong-error-handler');
boot(app, __dirname);

View File

@ -14,5 +14,6 @@
"principalType": "ROLE",
"principalId": "$owner"
}
]
}
],
"saltWorkFactor": 4
}

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../../../../index');
var boot = require('loopback-boot');
var app = module.exports = loopback({
@ -13,7 +14,7 @@ var errorHandler = require('strong-error-handler');
app.enableAuth();
boot(app, __dirname);
app.use(loopback.token({ model: app.models.AccessToken }));
app.use(loopback.token({model: app.models.AccessToken}));
var apiPath = '/api';
app.use(apiPath, loopback.rest());
app.use(loopback.urlNotFound());

View File

@ -3,12 +3,17 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('../');
var GeoPoint = loopback.GeoPoint;
describe('GeoPoint', function() {
describe('geoPoint.distanceTo(geoPoint, options)', function() {
it('Get the distance to another `GeoPoint`', function() {
var here = new GeoPoint({ lat: 10, lng: 10 });
var there = new GeoPoint({ lat: 5, lng: 5 });
var distance = here.distanceTo(there, { type: 'meters' });
var here = new GeoPoint({lat: 10, lng: 10});
var there = new GeoPoint({lat: 5, lng: 5});
var distance = here.distanceTo(there, {type: 'meters'});
assert.equal(Math.floor(distance), 782777);
});
@ -16,9 +21,9 @@ describe('GeoPoint', function() {
describe('GeoPoint.distanceBetween(a, b, options)', function() {
it('Get the distance between two points', function() {
var here = new GeoPoint({ lat: 10, lng: 10 });
var there = new GeoPoint({ lat: 5, lng: 5 });
var distance = GeoPoint.distanceBetween(here, there, { type: 'feet' });
var here = new GeoPoint({lat: 10, lng: 10});
var there = new GeoPoint({lat: 5, lng: 5});
var distance = GeoPoint.distanceBetween(here, there, {type: 'feet'});
assert.equal(Math.floor(distance), 2568169);
});
@ -48,7 +53,7 @@ describe('GeoPoint', function() {
});
it('Create as Model property', function() {
var Model = loopback.createModel('geo-model', {
geo: { type: 'GeoPoint' },
geo: {type: 'GeoPoint'},
});
var m = new Model({

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var _describe = {};
var _it = {};
var _beforeEach = {};
@ -68,7 +69,7 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) {
var app = this.app;
var model = app.models[modelName];
app.set('remoting', { errorHandler: { debug: true, log: false }});
app.set('remoting', {errorHandler: {debug: true, log: false}});
assert(model, 'cannot get model of name ' + modelName + ' from app.models');
assert(model.dataSource, 'cannot test model ' + modelName +
' without attached dataSource');
@ -135,7 +136,7 @@ _beforeEach.givenAnUnauthenticatedToken = function(attrs, optionalHandler) {
};
_beforeEach.givenAnAnonymousToken = function(attrs, optionalHandler) {
_beforeEach.givenModel('accessToken', { id: '$anonymous' }, optionalHandler);
_beforeEach.givenModel('accessToken', {id: '$anonymous'}, optionalHandler);
};
_describe.whenCalledRemotely = function(verb, url, data, cb) {

View File

@ -3,14 +3,17 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('../');
var request = require('supertest');
describe('hidden properties', function() {
beforeEach(function(done) {
var app = this.app = loopback();
var Product = this.Product = loopback.PersistedModel.extend('product',
{},
{ hidden: ['secret'] }
{hidden: ['secret']}
);
Product.attachTo(loopback.memory());

View File

@ -3,7 +3,11 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var expect = require('chai').expect;
var loopback = require('../');
var net = require('net');
describe('loopback application', function() {
it('pauses request stream during authentication', function(done) {
// This test reproduces the issue reported in
@ -38,10 +42,10 @@ describe('loopback application', function() {
loopback.AccessToken.attachTo(db);
loopback.Role.attachTo(db);
loopback.ACL.attachTo(db);
loopback.User.hasMany(loopback.AccessToken, { as: 'accessTokens' });
loopback.User.hasMany(loopback.AccessToken, {as: 'accessTokens'});
var Streamer = app.registry.createModel('Streamer');
app.model(Streamer, { dataSource: 'db' });
app.model(Streamer, {dataSource: 'db'});
Streamer.read = function(req, res, cb) {
var body = new Buffer(0);
req.on('data', function(chunk) {
@ -57,15 +61,15 @@ describe('loopback application', function() {
});
};
loopback.remoteMethod(Streamer.read, {
http: { method: 'post' },
http: {method: 'post'},
accepts: [
{ arg: 'req', type: 'Object', http: { source: 'req' }},
{ arg: 'res', type: 'Object', http: { source: 'res' }},
{arg: 'req', type: 'Object', http: {source: 'req'}},
{arg: 'res', type: 'Object', http: {source: 'res'}},
],
});
app.enableAuth();
app.use(loopback.token({ model: app.models.accessToken }));
app.use(loopback.token({model: app.models.accessToken}));
app.use(loopback.rest());
}

View File

@ -6,6 +6,7 @@
// Karma configuration
// http://karma-runner.github.io/0.12/config/configuration-file.html
'use strict';
module.exports = function(config) {
config.set({
// enable / disable watching file and executing tests whenever any file changes
@ -111,6 +112,6 @@ module.exports = function(config) {
},
// Add browserify to preprocessors
preprocessors: { 'test/*': ['browserify'] },
preprocessors: {'test/*': ['browserify']},
});
};

View File

@ -1,9 +1,10 @@
'use strict';
var expect = require('chai').expect;
var http = require('http');
var loopback = require('..');
var supertest = require('supertest');
var AN_OBJECT_VALUE = { name: 'an-object' };
var AN_OBJECT_VALUE = {name: 'an-object'};
describe('KeyValueModel', function() {
var request, app, CacheItem;
@ -61,7 +62,7 @@ describe('KeyValueModel', function() {
CacheItem.set('expire-key', AN_OBJECT_VALUE, function(err) {
if (err) return done(err);
request.put('/CacheItems/expire-key/expire')
.send({ ttl: 10 })
.send({ttl: 10})
.end(function(err, res) {
if (err) return done(err);
setTimeout(function() {
@ -77,7 +78,7 @@ describe('KeyValueModel', function() {
it('returns 404 when expiring a key that does not exist', function(done) {
request.put('/CacheItems/key-does-not-exist/expire')
.send({ ttl: 10 })
.send({ttl: 10})
.expect(404, done);
});
@ -138,7 +139,7 @@ describe('KeyValueModel', function() {
});
function setupAppAndCacheItem() {
app = loopback({ localRegistry: true, loadBuiltinModels: true });
app = loopback({localRegistry: true, loadBuiltinModels: true});
app.use(loopback.rest());
CacheItem = app.registry.createModel({
@ -146,8 +147,8 @@ describe('KeyValueModel', function() {
base: 'KeyValueModel',
});
app.dataSource('kv', { connector: 'kv-memory' });
app.model(CacheItem, { dataSource: 'kv' });
app.dataSource('kv', {connector: 'kv-memory'});
app.model(CacheItem, {dataSource: 'kv'});
}
var _server, _requestHandler; // eslint-disable-line one-var

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var it = require('./util/it');
var describe = require('./util/describe');
var Domain = require('domain');
@ -61,8 +62,6 @@ describe('loopback', function() {
'User',
'ValidationError',
'application',
'arguments',
'caller',
'configureModel',
'context',
'createContext',
@ -106,17 +105,17 @@ describe('loopback', function() {
describe('loopback(options)', function() {
it('supports localRegistry:true', function() {
var app = loopback({ localRegistry: true });
var app = loopback({localRegistry: true});
expect(app.registry).to.not.equal(loopback.registry);
});
it('does not load builtin models into the local registry', function() {
var app = loopback({ localRegistry: true });
var app = loopback({localRegistry: true});
expect(app.registry.findModel('User')).to.equal(undefined);
});
it('supports loadBuiltinModels:true', function() {
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
var app = loopback({localRegistry: true, loadBuiltinModels: true});
expect(app.registry.findModel('User'))
.to.have.property('modelName', 'User');
});
@ -150,7 +149,7 @@ describe('loopback', function() {
describe('loopback.remoteMethod(Model, fn, [options]);', function() {
it('Setup a remote method.', function() {
var Product = loopback.createModel('product', { price: Number });
var Product = loopback.createModel('product', {price: Number});
Product.stats = function(fn) {
// ...
@ -159,8 +158,8 @@ describe('loopback', function() {
loopback.remoteMethod(
Product.stats,
{
returns: { arg: 'stats', type: 'array' },
http: { path: '/info', verb: 'get' },
returns: {arg: 'stats', type: 'array'},
http: {path: '/info', verb: 'get'},
}
);
@ -187,7 +186,7 @@ describe('loopback', function() {
},
});
assert(MyCustomModel.super_ === MyModel);
assert.deepEqual(MyCustomModel.settings.foo, { bar: 'bat', bat: 'baz' });
assert.deepEqual(MyCustomModel.settings.foo, {bar: 'bat', bat: 'baz'});
assert(MyCustomModel.super_.modelName === MyModel.modelName);
});
});
@ -237,11 +236,11 @@ describe('loopback', function() {
methods: {
staticMethod: {
isStatic: true,
http: { path: '/static' },
http: {path: '/static'},
},
instanceMethod: {
isStatic: false,
http: { path: '/instance' },
http: {path: '/instance'},
},
},
});
@ -331,7 +330,7 @@ describe('loopback', function() {
});
it('updates relations before attaching to a dataSource', function() {
var db = loopback.createDataSource({ connector: loopback.Memory });
var db = loopback.createDataSource({connector: loopback.Memory});
var model = loopback.Model.extend(uniqueModelName);
// This test used to work because User model was already attached
@ -471,11 +470,11 @@ describe('loopback', function() {
methods: {
staticMethod: {
isStatic: true,
http: { path: '/static' },
http: {path: '/static'},
},
instanceMethod: {
isStatic: false,
http: { path: '/instance' },
http: {path: '/instance'},
},
},
});
@ -535,7 +534,7 @@ describe('loopback', function() {
dataSource: null,
methods: {
staticMethod: {
http: { path: '/static' },
http: {path: '/static'},
},
},
});
@ -551,7 +550,7 @@ describe('loopback', function() {
dataSource: null,
methods: {
'prototype.instanceMethod': {
http: { path: '/instance' },
http: {path: '/instance'},
},
},
});
@ -569,7 +568,7 @@ describe('loopback', function() {
methods: {
'prototype.instanceMethod': {
isStatic: true,
http: { path: '/instance' },
http: {path: '/instance'},
},
},
});
@ -584,7 +583,7 @@ describe('loopback', function() {
methods: {
staticMethod: {
isStatic: true,
http: { path: '/static' },
http: {path: '/static'},
},
},
});
@ -601,7 +600,7 @@ describe('loopback', function() {
methods: {
'prototype.instanceMethod': {
isStatic: false,
http: { path: '/instance' },
http: {path: '/instance'},
},
},
});
@ -621,7 +620,7 @@ describe('loopback', function() {
var Base = app.registry.createModel('Base', {}, {
methods: {
greet: {
http: { path: '/greet' },
http: {path: '/greet'},
},
},
});
@ -630,7 +629,7 @@ describe('loopback', function() {
base: 'Base',
methods: {
hello: {
http: { path: '/hello' },
http: {path: '/hello'},
},
},
});
@ -644,7 +643,7 @@ describe('loopback', function() {
var Base = app.registry.createModel('Base', {}, {
methods: {
greet: {
http: { path: '/greet' },
http: {path: '/greet'},
},
},
});
@ -653,7 +652,7 @@ describe('loopback', function() {
base: 'Base',
methods: {
greet: {
http: { path: '/hello' },
http: {path: '/hello'},
},
},
});
@ -662,13 +661,13 @@ describe('loopback', function() {
var customMethod = MyCustomModel.sharedClass.findMethodByName('greet');
// Base Method
expect(baseMethod.http).to.eql({ path: '/greet' });
expect(baseMethod.http).to.eql({path: '/greet'});
expect(baseMethod.http.path).to.equal('/greet');
expect(baseMethod.http.path).to.not.equal('/hello');
// Custom Method
expect(methodNames).to.include('greet');
expect(customMethod.http).to.eql({ path: '/hello' });
expect(customMethod.http).to.eql({path: '/hello'});
expect(customMethod.http.path).to.equal('/hello');
expect(customMethod.http.path).to.not.equal('/greet');
});
@ -679,7 +678,7 @@ describe('loopback', function() {
dataSource: null,
methods: {
greet: {
http: { path: '/greet' },
http: {path: '/greet'},
},
},
});
@ -688,7 +687,7 @@ describe('loopback', function() {
base: 'Base',
methods: {
hello: {
http: { path: '/hello' },
http: {path: '/hello'},
},
},
});
@ -709,7 +708,7 @@ describe('loopback', function() {
dataSource: null,
methods: {
greet: {
http: { path: '/greet' },
http: {path: '/greet'},
},
},
});
@ -718,7 +717,7 @@ describe('loopback', function() {
dataSource: null,
methods: {
hello: {
http: { path: '/hello' },
http: {path: '/hello'},
},
},
});
@ -731,7 +730,7 @@ describe('loopback', function() {
});
function setupLoopback() {
app = loopback({ localRegistry: true });
app = loopback({localRegistry: true});
}
function getAllMethodNamesWithoutClassName(Model) {

View File

@ -3,6 +3,10 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var loopback = require('../');
describe('Memory Connector', function() {
it('Create a model using the memory connector', function(done) {
// use the built in memory function
@ -25,9 +29,9 @@ describe('Memory Connector', function() {
var Product = memory.createModel('product', properties);
Product.create([
{ name: 'apple', price: 0.79 },
{ name: 'pear', price: 1.29 },
{ name: 'orange', price: 0.59 },
{name: 'apple', price: 0.79},
{name: 'pear', price: 1.29},
{name: 'orange', price: 0.59},
], count);
function count() {

View File

@ -1 +0,0 @@
--require ./test/support.js

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require(('../'));
var assert = require('assert');
var Application = loopback.Application;
@ -16,7 +17,7 @@ describe('Application', function() {
it('honors `application.register` - promise variant', function(done) {
Application.register('rfeng', 'MyTestApp',
{ description: 'My test application' }, function(err, result) {
{description: 'My test application'}, function(err, result) {
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyTestApp');
@ -28,7 +29,7 @@ describe('Application', function() {
it('honors `application.register` - promise variant', function(done) {
Application.register('rfeng', 'MyTestApp',
{ description: 'My test application' })
{description: 'My test application'})
.then(function(result) {
var app = result;
assert.equal(app.owner, 'rfeng');
@ -43,9 +44,9 @@ describe('Application', function() {
});
it('Create a new application', function(done) {
Application.create({ owner: 'rfeng',
Application.create({owner: 'rfeng',
name: 'MyApp1',
description: 'My first mobile application' }, function(err, result) {
description: 'My first mobile application'}, function(err, result) {
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp1');
@ -64,7 +65,7 @@ describe('Application', function() {
});
it('Create a new application with push settings', function(done) {
Application.create({ owner: 'rfeng',
Application.create({owner: 'rfeng',
name: 'MyAppWithPush',
description: 'My push mobile application',
pushSettings: {
@ -116,7 +117,7 @@ describe('Application', function() {
beforeEach(function(done) {
Application.register('rfeng', 'MyApp2',
{ description: 'My second mobile application' }, function(err, result) {
{description: 'My second mobile application'}, function(err, result) {
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp2');
@ -306,10 +307,10 @@ describe('Application', function() {
describe('Application subclass', function() {
it('should use subclass model name', function(done) {
var MyApp = Application.extend('MyApp');
var ds = loopback.createDataSource({ connector: loopback.Memory });
var ds = loopback.createDataSource({connector: loopback.Memory});
MyApp.attachTo(ds);
MyApp.register('rfeng', 'MyApp123',
{ description: 'My 123 mobile application' }, function(err, result) {
{description: 'My 123 mobile application'}, function(err, result) {
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp123');

View File

@ -3,6 +3,8 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var async = require('async');
var chai = require('chai');
var describe = require('./util/describe');
@ -11,6 +13,9 @@ var ACL = loopback.ACL;
var defineModelTestsWithDataSource = require('./util/model-tests');
var PersistedModel = loopback.PersistedModel;
var sinonChai = require('sinon-chai');
var Promise = require('bluebird');
var TaskEmitter = require('strong-task-emitter');
var request = require('supertest');
var expect = chai.expect;
chai.use(sinonChai);
@ -40,10 +45,10 @@ describe('Model / PersistedModel', function() {
User.attachTo(dataSource);
User.validatesUniquenessOf('email', { message: 'email is not unique' });
User.validatesUniquenessOf('email', {message: 'email is not unique'});
var joe = new User({ email: 'joe@joe.com' });
var joe2 = new User({ email: 'joe@joe.com' });
var joe = new User({email: 'joe@joe.com'});
var joe2 = new User({email: 'joe@joe.com'});
joe.save(function() {
joe2.save(function(err) {
@ -58,7 +63,7 @@ describe('Model / PersistedModel', function() {
describe('Model.attachTo(dataSource)', function() {
it('Attach a model to a [DataSource](#data-source)', function() {
var MyModel = loopback.createModel('my-model', { name: String });
var MyModel = loopback.createModel('my-model', {name: String});
var dataSource = loopback.createDataSource({
connector: loopback.Memory,
});
@ -77,11 +82,11 @@ describe.onServer('Remote Methods', function() {
var User, Post, dataSource, app;
beforeEach(function() {
app = loopback({ localRegistry: true, loadBuiltinModels: true });
app.set('remoting', { errorHandler: { debug: true, log: false }});
app = loopback({localRegistry: true, loadBuiltinModels: true});
app.set('remoting', {errorHandler: {debug: true, log: false}});
User = app.registry.createModel('user', {
id: { id: true, type: String, defaultFn: 'guid' },
id: {id: true, type: String, defaultFn: 'guid'},
'first': String,
'last': String,
'age': Number,
@ -94,17 +99,17 @@ describe.onServer('Remote Methods', function() {
});
Post = app.registry.createModel('post', {
id: { id: true, type: String, defaultFn: 'guid' },
id: {id: true, type: String, defaultFn: 'guid'},
title: String,
content: String,
}, {
trackChanges: true,
});
dataSource = app.dataSource('db', { connector: 'memory' });
dataSource = app.dataSource('db', {connector: 'memory'});
app.model(User, { dataSource: 'db' });
app.model(Post, { dataSource: 'db' });
app.model(User, {dataSource: 'db'});
app.model(Post, {dataSource: 'db'});
User.hasMany(Post);
@ -118,11 +123,11 @@ describe.onServer('Remote Methods', function() {
User.remoteMethod('login', {
accepts: [
{ arg: 'username', type: 'string', required: true },
{ arg: 'password', type: 'string', required: true },
{arg: 'username', type: 'string', required: true},
{arg: 'password', type: 'string', required: true},
],
returns: { arg: 'sessionId', type: 'any', root: true },
http: { path: '/sign-in', verb: 'get' },
returns: {arg: 'sessionId', type: 'any', root: true},
http: {path: '/sign-in', verb: 'get'},
});
app.use(loopback.rest());
@ -130,7 +135,7 @@ describe.onServer('Remote Methods', function() {
describe('Model.create(data, callback)', function() {
it('creates model', function(done) {
var anObject = { first: 'June' };
var anObject = {first: 'June'};
request(app)
.post('/users')
// sends an object
@ -148,7 +153,7 @@ describe.onServer('Remote Methods', function() {
// coercion being done on strong-remoting side
it('creates array of models', function(done) {
var arrayOfObjects = [
{ first: 'John' }, { first: 'Jane' },
{first: 'John'}, {first: 'Jane'},
];
request(app)
.post('/users')
@ -169,11 +174,11 @@ describe.onServer('Remote Methods', function() {
describe('Model.destroyAll(callback)', function() {
it('Delete all Model instances from data source', function(done) {
(new TaskEmitter())
.task(User, 'create', { first: 'jill' })
.task(User, 'create', { first: 'bob' })
.task(User, 'create', { first: 'jan' })
.task(User, 'create', { first: 'sam' })
.task(User, 'create', { first: 'suzy' })
.task(User, 'create', {first: 'jill'})
.task(User, 'create', {first: 'bob'})
.task(User, 'create', {first: 'jan'})
.task(User, 'create', {first: 'sam'})
.task(User, 'create', {first: 'suzy'})
.on('done', function() {
User.count(function(err, count) {
User.destroyAll(function() {
@ -192,10 +197,10 @@ describe.onServer('Remote Methods', function() {
it('Updates when a Model instance is retreived from data source', function(done) {
var taskEmitter = new TaskEmitter();
taskEmitter
.task(User, 'create', { first: 'jill', second: 'pill' })
.task(User, 'create', { first: 'bob', second: 'sob' })
.task(User, 'create', {first: 'jill', second: 'pill'})
.task(User, 'create', {first: 'bob', second: 'sob'})
.on('done', function() {
User.upsertWithWhere({ second: 'pill' }, { second: 'jones' }, function(err, user) {
User.upsertWithWhere({second: 'pill'}, {second: 'jones'}, function(err, user) {
if (err) return done(err);
var id = user.id;
User.findById(id, function(err, user) {
@ -210,9 +215,9 @@ describe.onServer('Remote Methods', function() {
it('Creates when no Model instance is retreived from data source', function(done) {
var taskEmitter = new TaskEmitter();
taskEmitter
.task(User, 'create', { first: 'simon', second: 'somers' })
.task(User, 'create', {first: 'simon', second: 'somers'})
.on('done', function() {
User.upsertWithWhere({ first: 'somers' }, { first: 'Simon' }, function(err, user) {
User.upsertWithWhere({first: 'somers'}, {first: 'Simon'}, function(err, user) {
if (err) return done(err);
var id = user.id;
User.findById(id, function(err, user) {
@ -258,7 +263,7 @@ describe.onServer('Remote Methods', function() {
it('Call the findById with filter.fields using HTTP / REST', function(done) {
request(app)
.post('/users')
.send({ first: 'x', last: 'y' })
.send({first: 'x', last: 'y'})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -284,7 +289,7 @@ describe.onServer('Remote Methods', function() {
it('Call the findById with filter.include using HTTP / REST', function(done) {
request(app)
.post('/users')
.send({ first: 'x', last: 'y' })
.send({first: 'x', last: 'y'})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -294,7 +299,7 @@ describe.onServer('Remote Methods', function() {
assert(userId);
request(app)
.post('/users/' + userId + '/posts')
.send({ title: 'T1', content: 'C1' })
.send({title: 'T1', content: 'C1'})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -332,7 +337,7 @@ describe.onServer('Remote Methods', function() {
// invoke save
request(app)
.post('/users')
.send({ data: { first: 'foo', last: 'bar' }})
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -360,7 +365,7 @@ describe.onServer('Remote Methods', function() {
// invoke save
request(app)
.post('/users')
.send({ data: { first: 'foo', last: 'bar' }})
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -392,7 +397,7 @@ describe.onServer('Remote Methods', function() {
// invoke save
request(app)
.post('/users')
.send({ data: { first: 'foo', last: 'bar' }})
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -447,7 +452,7 @@ describe.onServer('Remote Methods', function() {
// invoke save
request(app)
.post('/users')
.send({ data: { first: 'foo', last: 'bar' }})
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -479,7 +484,7 @@ describe.onServer('Remote Methods', function() {
// invoke save
request(app)
.post('/users')
.send({ data: { first: 'foo', last: 'bar' }})
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
@ -495,20 +500,20 @@ describe.onServer('Remote Methods', function() {
describe('Model.hasMany(Model)', function() {
it('Define a one to many relationship', function(done) {
var Book = dataSource.createModel('book', { title: String, author: String });
var Chapter = dataSource.createModel('chapter', { title: String });
var Book = dataSource.createModel('book', {title: String, author: String});
var Chapter = dataSource.createModel('chapter', {title: String});
// by referencing model
Book.hasMany(Chapter);
Book.create({ title: 'Into the Wild', author: 'Jon Krakauer' }, function(err, book) {
Book.create({title: 'Into the Wild', author: 'Jon Krakauer'}, function(err, book) {
// using 'chapters' scope for build:
var c = book.chapters.build({ title: 'Chapter 1' });
book.chapters.create({ title: 'Chapter 2' }, function() {
var c = book.chapters.build({title: 'Chapter 1'});
book.chapters.create({title: 'Chapter 2'}, function() {
c.save(function() {
Chapter.count({ bookId: book.id }, function(err, count) {
Chapter.count({bookId: book.id}, function(err, count) {
assert.equal(count, 2);
book.chapters({ where: { title: 'Chapter 1' }}, function(err, chapters) {
book.chapters({where: {title: 'Chapter 1'}}, function(err, chapters) {
assert.equal(chapters.length, 1);
assert.equal(chapters[0].title, 'Chapter 1');
@ -525,8 +530,8 @@ describe.onServer('Remote Methods', function() {
it('Normalized properties passed in originally by loopback.createModel()', function() {
var props = {
s: String,
n: { type: 'Number' },
o: { type: 'String', min: 10, max: 100 },
n: {type: 'Number'},
o: {type: 'String', min: 10, max: 100},
d: Date,
g: loopback.GeoPoint,
};
@ -635,7 +640,7 @@ describe.onServer('Remote Methods', function() {
function shouldReturn(methodName, expectedAccessType) {
describe(methodName, function() {
it('should return ' + expectedAccessType, function() {
var remoteMethod = { name: methodName };
var remoteMethod = {name: methodName};
assert.equal(
User._getAccessTypeForMethod(remoteMethod),
expectedAccessType
@ -712,8 +717,8 @@ describe.onServer('Remote Methods', function() {
it('includes all aliases', function() {
var app = loopback();
var model = PersistedModel.extend('PersistedModelForAliases');
app.dataSource('db', { connector: 'memory' });
app.model(model, { dataSource: 'db' });
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
// this code is used by loopback-sdk-angular codegen
var metadata = app.handler('rest')
@ -760,8 +765,8 @@ describe.onServer('Remote Methods', function() {
it('emits a `remoteMethodDisabled` event', function() {
var app = loopback();
var model = PersistedModel.extend('TestModelForDisablingRemoteMethod');
app.dataSource('db', { connector: 'memory' });
app.model(model, { dataSource: 'db' });
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
var callbackSpy = require('sinon').spy();
var TestModel = app.models.TestModelForDisablingRemoteMethod;
@ -774,8 +779,8 @@ describe.onServer('Remote Methods', function() {
it('emits a `remoteMethodDisabled` event from disableRemoteMethodByName', function() {
var app = loopback();
var model = PersistedModel.extend('TestModelForDisablingRemoteMethod');
app.dataSource('db', { connector: 'memory' });
app.model(model, { dataSource: 'db' });
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
var callbackSpy = require('sinon').spy();
var TestModel = app.models.TestModelForDisablingRemoteMethod;
@ -791,11 +796,11 @@ describe.onServer('Remote Methods', function() {
beforeEach(function setup() {
app = loopback();
TestModel = loopback.createModel('TestModelForGetApp'); // unique name
app.dataSource('db', { connector: 'memory' });
app.dataSource('db', {connector: 'memory'});
});
it('calls the callback when already attached', function(done) {
app.model(TestModel, { dataSource: 'db' });
app.model(TestModel, {dataSource: 'db'});
TestModel.getApp(function(err, a) {
if (err) return done(err);
@ -814,7 +819,7 @@ describe.onServer('Remote Methods', function() {
done();
});
app.model(TestModel, { dataSource: 'db' });
app.model(TestModel, {dataSource: 'db'});
// fails on time-out when not implemented correctly
});
});

View File

@ -3,12 +3,17 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var assert = require('assert');
var expect = require('chai').expect;
var loopback = require('../');
describe('Registry', function() {
describe('createModel', function() {
it('should throw error upon extending non-exist base model', function() {
var app = loopback();
var props = {};
var opts = { base: 'nonexistent' };
var opts = {base: 'nonexistent'};
expect(function() { app.registry.createModel('aModel', props, opts); })
.to.throw(/model\s`aModel`(.*)unknown\smodel\s`nonexistent`/);
});
@ -20,32 +25,32 @@ describe('Registry', function() {
var appBar = loopback();
var modelName = 'MyModel';
var subModelName = 'Sub' + modelName;
var settings = { base: 'PersistedModel' };
var settings = {base: 'PersistedModel'};
appFoo.set('perAppRegistries', true);
appBar.set('perAppRegistries', true);
var dsFoo = appFoo.dataSource('dsFoo', { connector: 'memory' });
var dsBar = appFoo.dataSource('dsBar', { connector: 'memory' });
var dsFoo = appFoo.dataSource('dsFoo', {connector: 'memory'});
var dsBar = appFoo.dataSource('dsBar', {connector: 'memory'});
var FooModel = appFoo.registry.createModel(modelName, {}, settings);
appFoo.model(FooModel, { dataSource: dsFoo });
appFoo.model(FooModel, {dataSource: dsFoo});
var FooSubModel = appFoo.registry.createModel(subModelName, {}, settings);
appFoo.model(FooSubModel, { dataSource: dsFoo });
appFoo.model(FooSubModel, {dataSource: dsFoo});
var BarModel = appBar.registry.createModel(modelName, {}, settings);
appBar.model(BarModel, { dataSource: dsBar });
appBar.model(BarModel, {dataSource: dsBar});
var BarSubModel = appBar.registry.createModel(subModelName, {}, settings);
appBar.model(BarSubModel, { dataSource: dsBar });
appBar.model(BarSubModel, {dataSource: dsBar});
FooModel.hasMany(FooSubModel);
BarModel.hasMany(BarSubModel);
expect(appFoo.models[modelName]).to.not.equal(appBar.models[modelName]);
BarModel.create({ name: 'bar' }, function(err, bar) {
BarModel.create({name: 'bar'}, function(err, bar) {
assert(!err);
bar.subMyModels.create({ parent: 'bar' }, function(err) {
bar.subMyModels.create({parent: 'bar'}, function(err) {
assert(!err);
FooSubModel.find(function(err, foos) {
assert(!err);

View File

@ -3,6 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('../');
var lt = require('./helpers/loopback-testing-helper');
var path = require('path');
@ -31,22 +32,22 @@ describe('relations - integration', function() {
describe('polymorphicHasMany', function() {
before(function defineProductAndCategoryModels() {
var Team = app.registry.createModel('Team', { name: 'string' });
var Reader = app.registry.createModel('Reader', { name: 'string' });
var Team = app.registry.createModel('Team', {name: 'string'});
var Reader = app.registry.createModel('Reader', {name: 'string'});
var Picture = app.registry.createModel('Picture',
{ name: 'string', imageableId: 'number', imageableType: 'string' });
{name: 'string', imageableId: 'number', imageableType: 'string'});
app.model(Team, { dataSource: 'db' });
app.model(Reader, { dataSource: 'db' });
app.model(Picture, { dataSource: 'db' });
app.model(Team, {dataSource: 'db'});
app.model(Reader, {dataSource: 'db'});
app.model(Picture, {dataSource: 'db'});
Reader.hasMany(Picture, { polymorphic: { // alternative syntax
Reader.hasMany(Picture, {polymorphic: { // alternative syntax
as: 'imageable', // if not set, default to: reference
foreignKey: 'imageableId', // defaults to 'as + Id'
discriminator: 'imageableType', // defaults to 'as + Type'
}});
Picture.belongsTo('imageable', { polymorphic: {
Picture.belongsTo('imageable', {polymorphic: {
foreignKey: 'imageableId',
discriminator: 'imageableType',
}});
@ -56,18 +57,18 @@ describe('relations - integration', function() {
before(function createEvent(done) {
var test = this;
app.models.Team.create({ name: 'Team 1' },
app.models.Team.create({name: 'Team 1'},
function(err, team) {
if (err) return done(err);
test.team = team;
app.models.Reader.create({ name: 'Reader 1' },
app.models.Reader.create({name: 'Reader 1'},
function(err, reader) {
if (err) return done(err);
test.reader = reader;
reader.pictures.create({ name: 'Picture 1' });
reader.pictures.create({ name: 'Picture 2' });
reader.pictures.create({name: 'Picture 1'});
reader.pictures.create({name: 'Picture 2'});
reader.team(test.team);
reader.save(done);
});
@ -82,14 +83,14 @@ describe('relations - integration', function() {
it('includes the related child model', function(done) {
var url = '/api/readers/' + this.reader.id;
this.get(url)
.query({ 'filter': { 'include': 'pictures' }})
.query({'filter': {'include': 'pictures'}})
.expect(200, function(err, res) {
if (err) return done(err);
expect(res.body.name).to.be.equal('Reader 1');
expect(res.body.pictures).to.be.eql([
{ name: 'Picture 1', id: 1, imageableId: 1, imageableType: 'Reader' },
{ name: 'Picture 2', id: 2, imageableId: 1, imageableType: 'Reader' },
{name: 'Picture 1', id: 1, imageableId: 1, imageableType: 'Reader'},
{name: 'Picture 2', id: 2, imageableId: 1, imageableType: 'Reader'},
]);
done();
@ -99,13 +100,13 @@ describe('relations - integration', function() {
it('includes the related parent model', function(done) {
var url = '/api/pictures';
this.get(url)
.query({ 'filter': { 'include': 'imageable' }})
.query({'filter': {'include': 'imageable'}})
.expect(200, function(err, res) {
if (err) return done(err);
expect(res.body[0].name).to.be.equal('Picture 1');
expect(res.body[1].name).to.be.equal('Picture 2');
expect(res.body[0].imageable).to.be.eql({ name: 'Reader 1', id: 1, teamId: 1 });
expect(res.body[0].imageable).to.be.eql({name: 'Reader 1', id: 1, teamId: 1});
done();
});
@ -114,9 +115,9 @@ describe('relations - integration', function() {
it('includes related models scoped to the related parent model', function(done) {
var url = '/api/pictures';
this.get(url)
.query({ 'filter': { 'include': {
.query({'filter': {'include': {
'relation': 'imageable',
'scope': { 'include': 'team' },
'scope': {'include': 'team'},
}}})
.expect(200, function(err, res) {
if (err) return done(err);
@ -124,7 +125,7 @@ describe('relations - integration', function() {
expect(res.body[0].name).to.be.equal('Picture 1');
expect(res.body[1].name).to.be.equal('Picture 2');
expect(res.body[0].imageable.name).to.be.eql('Reader 1');
expect(res.body[0].imageable.team).to.be.eql({ name: 'Team 1', id: 1 });
expect(res.body[0].imageable.team).to.be.eql({name: 'Team 1', id: 1});
done();
});
@ -239,7 +240,7 @@ describe('relations - integration', function() {
it('does not add default properties to request body', function(done) {
var self = this;
self.request.put(self.url)
.send({ active: true })
.send({active: true})
.end(function(err) {
if (err) return done(err);
app.models.Widget.findById(self.widget.id, function(err, w) {
@ -453,7 +454,7 @@ describe('relations - integration', function() {
});
var NOW = Date.now();
var data = { date: new Date(NOW) };
var data = {date: new Date(NOW)};
lt.describe.whenCalledRemotely('PUT', '/api/physicians/:id/patients/rel/:fk', data, function() {
it('should succeed with statusCode 200', function() {
@ -661,14 +662,14 @@ describe('relations - integration', function() {
var product = app.registry.createModel(
'product',
{ id: 'string', name: 'string' }
{id: 'string', name: 'string'}
);
var category = app.registry.createModel(
'category',
{ id: 'string', name: 'string' }
{id: 'string', name: 'string'}
);
app.model(product, { dataSource: 'db' });
app.model(category, { dataSource: 'db' });
app.model(product, {dataSource: 'db'});
app.model(category, {dataSource: 'db'});
product.hasAndBelongsToMany(category);
category.hasAndBelongsToMany(product);
@ -690,11 +691,11 @@ describe('relations - integration', function() {
});
beforeEach(function createAnotherCategoryAndProduct(done) {
app.models.category.create({ name: 'another-category' },
app.models.category.create({name: 'another-category'},
function(err, cat) {
if (err) return done(err);
cat.products.create({ name: 'another-product' }, done);
cat.products.create({name: 'another-product'}, done);
});
});
@ -784,23 +785,23 @@ describe('relations - integration', function() {
describe('embedsOne', function() {
before(function defineGroupAndPosterModels() {
var group = app.registry.createModel('group',
{ name: 'string' },
{ plural: 'groups' }
{name: 'string'},
{plural: 'groups'}
);
app.model(group, { dataSource: 'db' });
app.model(group, {dataSource: 'db'});
var poster = app.registry.createModel(
'poster',
{ url: 'string' }
{url: 'string'}
);
app.model(poster, { dataSource: 'db' });
app.model(poster, {dataSource: 'db'});
group.embedsOne(poster, { as: 'cover' });
group.embedsOne(poster, {as: 'cover'});
});
before(function createImage(done) {
var test = this;
app.models.group.create({ name: 'Group 1' },
app.models.group.create({name: 'Group 1'},
function(err, group) {
if (err) return done(err);
@ -818,10 +819,10 @@ describe('relations - integration', function() {
var url = '/api/groups/' + this.group.id + '/cover';
this.post(url)
.send({ url: 'http://image.url' })
.send({url: 'http://image.url'})
.expect(200, function(err, res) {
expect(res.body).to.be.eql(
{ url: 'http://image.url' }
{url: 'http://image.url'}
);
done();
@ -837,7 +838,7 @@ describe('relations - integration', function() {
expect(res.body.name).to.be.equal('Group 1');
expect(res.body.poster).to.be.eql(
{ url: 'http://image.url' }
{url: 'http://image.url'}
);
done();
@ -852,7 +853,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql(
{ url: 'http://image.url' }
{url: 'http://image.url'}
);
done();
@ -863,7 +864,7 @@ describe('relations - integration', function() {
var url = '/api/groups/' + this.group.id + '/cover';
this.put(url)
.send({ url: 'http://changed.url' })
.send({url: 'http://changed.url'})
.expect(200, function(err, res) {
expect(res.body.url).to.be.equal('http://changed.url');
@ -879,7 +880,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql(
{ url: 'http://changed.url' }
{url: 'http://changed.url'}
);
done();
@ -901,29 +902,29 @@ describe('relations - integration', function() {
before(function defineProductAndCategoryModels() {
var todoList = app.registry.createModel(
'todoList',
{ name: 'string' },
{ plural: 'todo-lists' }
{name: 'string'},
{plural: 'todo-lists'}
);
app.model(todoList, { dataSource: 'db' });
app.model(todoList, {dataSource: 'db'});
var todoItem = app.registry.createModel(
'todoItem',
{ content: 'string' }, { forceId: false }
{content: 'string'}, {forceId: false}
);
app.model(todoItem, { dataSource: 'db' });
app.model(todoItem, {dataSource: 'db'});
todoList.embedsMany(todoItem, { as: 'items' });
todoList.embedsMany(todoItem, {as: 'items'});
});
before(function createTodoList(done) {
var test = this;
app.models.todoList.create({ name: 'List A' },
app.models.todoList.create({name: 'List A'},
function(err, list) {
if (err) return done(err);
test.todoList = list;
list.items.build({ content: 'Todo 1' });
list.items.build({ content: 'Todo 2' });
list.items.build({content: 'Todo 1'});
list.items.build({content: 'Todo 2'});
list.save(done);
});
});
@ -941,8 +942,8 @@ describe('relations - integration', function() {
expect(res.body.name).to.be.equal('List A');
expect(res.body.todoItems).to.be.eql([
{ content: 'Todo 1', id: 1 },
{ content: 'Todo 2', id: 2 },
{content: 'Todo 1', id: 1},
{content: 'Todo 2', id: 2},
]);
done();
@ -957,8 +958,8 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ content: 'Todo 1', id: 1 },
{ content: 'Todo 2', id: 2 },
{content: 'Todo 1', id: 1},
{content: 'Todo 2', id: 2},
]);
done();
@ -974,7 +975,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ content: 'Todo 2', id: 2 },
{content: 'Todo 2', id: 2},
]);
done();
@ -984,10 +985,10 @@ describe('relations - integration', function() {
it('creates embedded models', function(done) {
var url = '/api/todo-lists/' + this.todoList.id + '/items';
var expected = { content: 'Todo 3', id: 3 };
var expected = {content: 'Todo 3', id: 3};
this.post(url)
.send({ content: 'Todo 3' })
.send({content: 'Todo 3'})
.expect(200, function(err, res) {
expect(res.body).to.be.eql(expected);
@ -1003,9 +1004,9 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ content: 'Todo 1', id: 1 },
{ content: 'Todo 2', id: 2 },
{ content: 'Todo 3', id: 3 },
{content: 'Todo 1', id: 1},
{content: 'Todo 2', id: 2},
{content: 'Todo 3', id: 3},
]);
done();
@ -1020,7 +1021,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql(
{ content: 'Todo 3', id: 3 }
{content: 'Todo 3', id: 3}
);
done();
@ -1045,8 +1046,8 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ content: 'Todo 1', id: 1 },
{ content: 'Todo 3', id: 3 },
{content: 'Todo 1', id: 1},
{content: 'Todo 3', id: 3},
]);
done();
@ -1089,48 +1090,48 @@ describe('relations - integration', function() {
before(function defineProductAndCategoryModels() {
var recipe = app.registry.createModel(
'recipe',
{ name: 'string' }
{name: 'string'}
);
app.model(recipe, { dataSource: 'db' });
app.model(recipe, {dataSource: 'db'});
var ingredient = app.registry.createModel(
'ingredient',
{ name: 'string' }
{name: 'string'}
);
app.model(ingredient, { dataSource: 'db' });
app.model(ingredient, {dataSource: 'db'});
var photo = app.registry.createModel(
'photo',
{ name: 'string' }
{name: 'string'}
);
app.model(photo, { dataSource: 'db' });
app.model(photo, {dataSource: 'db'});
recipe.referencesMany(ingredient);
// contrived example for test:
recipe.hasOne(photo, { as: 'picture', options: {
http: { path: 'image' },
recipe.hasOne(photo, {as: 'picture', options: {
http: {path: 'image'},
}});
});
before(function createRecipe(done) {
var test = this;
app.models.recipe.create({ name: 'Recipe' },
app.models.recipe.create({name: 'Recipe'},
function(err, recipe) {
if (err) return done(err);
test.recipe = recipe;
recipe.ingredients.create({
name: 'Chocolate' },
name: 'Chocolate'},
function(err, ing) {
test.ingredient1 = ing.id;
recipe.picture.create({ name: 'Photo 1' }, done);
recipe.picture.create({name: 'Photo 1'}, done);
});
});
});
before(function createIngredient(done) {
var test = this;
app.models.ingredient.create({ name: 'Sugar' }, function(err, ing) {
app.models.ingredient.create({name: 'Sugar'}, function(err, ing) {
test.ingredient2 = ing.id;
done();
@ -1166,7 +1167,7 @@ describe('relations - integration', function() {
var test = this;
this.post(url)
.send({ name: 'Butter' })
.send({name: 'Butter'})
.expect(200, function(err, res) {
expect(res.body.name).to.be.eql('Butter');
test.ingredient3 = res.body.id;
@ -1184,9 +1185,9 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{ name: 'Sugar', id: test.ingredient2 },
{ name: 'Butter', id: test.ingredient3 },
{name: 'Chocolate', id: test.ingredient1},
{name: 'Sugar', id: test.ingredient2},
{name: 'Butter', id: test.ingredient3},
]);
done();
@ -1202,8 +1203,8 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{ name: 'Butter', id: test.ingredient3 },
{name: 'Chocolate', id: test.ingredient1},
{name: 'Butter', id: test.ingredient3},
]);
done();
@ -1220,7 +1221,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Butter', id: test.ingredient3 },
{name: 'Butter', id: test.ingredient3},
]);
done();
@ -1240,8 +1241,8 @@ describe('relations - integration', function() {
test.ingredient1, test.ingredient3,
]);
expect(res.body.ingredients).to.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{ name: 'Butter', id: test.ingredient3 },
{name: 'Chocolate', id: test.ingredient1},
{name: 'Butter', id: test.ingredient3},
]);
done();
@ -1258,7 +1259,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql(
{ name: 'Butter', id: test.ingredient3 }
{name: 'Butter', id: test.ingredient3}
);
done();
@ -1302,8 +1303,8 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{ name: 'Sugar', id: test.ingredient2 },
{name: 'Chocolate', id: test.ingredient1},
{name: 'Sugar', id: test.ingredient2},
]);
done();
@ -1319,7 +1320,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{name: 'Chocolate', id: test.ingredient1},
]);
done();
@ -1334,7 +1335,7 @@ describe('relations - integration', function() {
this.put(url)
.expect(200, function(err, res) {
expect(res.body).to.be.eql(
{ name: 'Sugar', id: test.ingredient2 }
{name: 'Sugar', id: test.ingredient2}
);
done();
@ -1350,8 +1351,8 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{ name: 'Sugar', id: test.ingredient2 },
{name: 'Chocolate', id: test.ingredient1},
{name: 'Sugar', id: test.ingredient2},
]);
done();
@ -1378,7 +1379,7 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Sugar', id: test.ingredient2 },
{name: 'Sugar', id: test.ingredient2},
]);
done();
@ -1394,8 +1395,8 @@ describe('relations - integration', function() {
if (err) return done(err);
expect(res.body).to.be.eql([
{ name: 'Chocolate', id: test.ingredient1 },
{ name: 'Sugar', id: test.ingredient2 },
{name: 'Chocolate', id: test.ingredient1},
{name: 'Sugar', id: test.ingredient2},
]);
done();
@ -1441,38 +1442,38 @@ describe('relations - integration', function() {
before(function defineModels() {
var Book = app.registry.createModel(
'Book',
{ name: 'string' },
{ plural: 'books' }
{name: 'string'},
{plural: 'books'}
);
app.model(Book, { dataSource: 'db' });
app.model(Book, {dataSource: 'db'});
var Page = app.registry.createModel(
'Page',
{ name: 'string' },
{ plural: 'pages' }
{name: 'string'},
{plural: 'pages'}
);
app.model(Page, { dataSource: 'db' });
app.model(Page, {dataSource: 'db'});
var Image = app.registry.createModel(
'Image',
{ name: 'string' },
{ plural: 'images' }
{name: 'string'},
{plural: 'images'}
);
app.model(Image, { dataSource: 'db' });
app.model(Image, {dataSource: 'db'});
var Note = app.registry.createModel(
'Note',
{ text: 'string' },
{ plural: 'notes' }
{text: 'string'},
{plural: 'notes'}
);
app.model(Note, { dataSource: 'db' });
app.model(Note, {dataSource: 'db'});
var Chapter = app.registry.createModel(
'Chapter',
{ name: 'string' },
{ plural: 'chapters' }
{name: 'string'},
{plural: 'chapters'}
);
app.model(Chapter, { dataSource: 'db' });
app.model(Chapter, {dataSource: 'db'});
Book.hasMany(Page);
Book.hasMany(Chapter);
@ -1485,7 +1486,7 @@ describe('relations - integration', function() {
throw new Error('This should not crash the app');
};
Page.remoteMethod('__throw__errors', { isStatic: false, http: { path: '/throws', verb: 'get' }});
Page.remoteMethod('__throw__errors', {isStatic: false, http: {path: '/throws', verb: 'get'}});
Book.nestRemoting('pages');
Book.nestRemoting('chapters');
@ -1509,17 +1510,17 @@ describe('relations - integration', function() {
before(function createBook(done) {
var test = this;
app.models.Book.create({ name: 'Book 1' },
app.models.Book.create({name: 'Book 1'},
function(err, book) {
if (err) return done(err);
test.book = book;
book.pages.create({ name: 'Page 1' },
book.pages.create({name: 'Page 1'},
function(err, page) {
if (err) return done(err);
test.page = page;
page.notes.create({ text: 'Page Note 1' },
page.notes.create({text: 'Page Note 1'},
function(err, note) {
test.note = note;
@ -1531,12 +1532,12 @@ describe('relations - integration', function() {
before(function createChapters(done) {
var test = this;
test.book.chapters.create({ name: 'Chapter 1' },
test.book.chapters.create({name: 'Chapter 1'},
function(err, chapter) {
if (err) return done(err);
test.chapter = chapter;
chapter.notes.create({ text: 'Chapter Note 1' }, function(err, note) {
chapter.notes.create({text: 'Chapter Note 1'}, function(err, note) {
test.cnote = note;
done();
@ -1546,7 +1547,7 @@ describe('relations - integration', function() {
before(function createCover(done) {
var test = this;
app.models.Image.create({ name: 'Cover 1', book: test.book },
app.models.Image.create({name: 'Cover 1', book: test.book},
function(err, image) {
if (err) return done(err);
@ -1705,7 +1706,7 @@ describe('relations - integration', function() {
before(function createCustomer(done) {
var test = this;
app.models.customer.create({ name: 'John' }, function(err, c) {
app.models.customer.create({name: 'John'}, function(err, c) {
if (err) return done(err);
cust = c;
@ -1727,7 +1728,7 @@ describe('relations - integration', function() {
var url = '/api/customers/' + cust.id + '/profile';
this.post(url)
.send({ points: 10 })
.send({points: 10})
.expect(200, function(err, res) {
if (err) return done(err);
@ -1754,7 +1755,7 @@ describe('relations - integration', function() {
it('should not create the referenced model twice', function(done) {
var url = '/api/customers/' + cust.id + '/profile';
this.post(url)
.send({ points: 20 })
.send({points: 20})
.expect(500, function(err, res) {
done(err);
});
@ -1763,7 +1764,7 @@ describe('relations - integration', function() {
it('should update the referenced model', function(done) {
var url = '/api/customers/' + cust.id + '/profile';
this.put(url)
.send({ points: 100 })
.send({points: 100})
.expect(200, function(err, res) {
if (err) return done(err);

Some files were not shown because too many files have changed in this diff Show More