Merge branch 'release/1.3.3' into production
This commit is contained in:
commit
9f61bcaccb
294
LICENSE
294
LICENSE
|
@ -1,4 +1,10 @@
|
|||
Copyright (c) 2013 StrongLoop, Inc.
|
||||
Copyright (c) 2013-2014 StrongLoop, Inc.
|
||||
|
||||
loopback-datasource-juggler uses a 'dual license' model. Users may use
|
||||
loopback-datasource-juggler under the terms of the MIT license, or under the
|
||||
StrongLoop License. The text of both is included below.
|
||||
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -17,3 +23,289 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
StrongLoop License
|
||||
|
||||
STRONGLOOP SUBSCRIPTION AGREEMENT
|
||||
PLEASE READ THIS AGREEMENT CAREFULLY BEFORE YOU AGREE TO THESE TERMS. IF YOU
|
||||
ARE ACTING ON BEHALF OF AN ENTITY, THEN YOU REPRESENT THAT YOU HAVE THE
|
||||
AUTHORITY TO ENTER INTO THIS AGREEMENT ON BEHALF OF THAT ENTITY. IF YOU DO NOT
|
||||
AGREE TO THESE TERMS, YOU SHOULD NOT AGREE TO THE TERMS OF THIS AGREEMENT OR
|
||||
INSTALL OR USE THE SOFTWARE.
|
||||
This StrongLoop Subscription Agreement ("Agreement") is made by and between
|
||||
StrongLoop, Inc. ("StrongLoop") with its principal place of business at 107 S.
|
||||
B St, Suite 220, San Mateo, CA 94401 and the person or entity entering into this
|
||||
Agreement ("Customer"). The effective date ("Effective Date") of this Agreement
|
||||
is the date Customer agrees to these terms or installs or uses the Software (as
|
||||
defined below). This Agreement applies to Customer's use of the Software but it
|
||||
shall be superseded by any signed agreement between you and StrongLoop
|
||||
concerning the Software.
|
||||
1. Subscriptions and Licenses.
|
||||
1.1 Subscriptions. StrongLoop offers five different subscription levels to its
|
||||
customers, each as more particularly described on StrongLoop's website located
|
||||
at www.strongloop.com (the "StrongLoop Site"): (1) Free; (2) Developer; (3)
|
||||
Professional; (4) Gold; and (5) Platinum. The actual subscription level
|
||||
applicable to Customer (the "Subscription") will be specified in the purchase
|
||||
order that Customer issues to StrongLoop. This Agreement applies to Customer
|
||||
regardless of the level of the Subscription selected by Customer and whether or
|
||||
not Customer upgrades or downgrades its Subscription. StrongLoop hereby agrees
|
||||
to provide the services as described on the StrongLoop Site for each
|
||||
Subscription level during the term for which Customer has purchased the
|
||||
applicable Subscription, subject to Customer paying the fees applicable to the
|
||||
Subscription level purchased, if any (the "Subscription Fees"). StrongLoop may
|
||||
modify the services to be provided under any Subscription upon notice to
|
||||
Customer.
|
||||
1.2 License Grant. Subject to the terms and conditions of this Agreement,
|
||||
StrongLoop grants to Customer, during the Subscription Term (as defined in
|
||||
Section 7.1 (Term and Termination) of this Agreement, a limited, non-exclusive,
|
||||
non-transferable right and license, to install and use the StrongLoop Suite
|
||||
software (the "Software") and the documentation made available electronically as
|
||||
part of the Software (the "Documentation"), either of which may be modified
|
||||
during the Term (as defined in Section 7.1 below), solely for development,
|
||||
production and commercial purposes so long as Customer is using the Software to
|
||||
run only one process on a given operating system at a time. This Agreement,
|
||||
including but not limited to the license and restrictions contained herein,
|
||||
apply to Customer regardless of whether Customer accesses the Software via
|
||||
download from the StrongLoop Site or through a third-party website or service,
|
||||
even if Customer acquired the Software prior to agreeing to this Agreement.
|
||||
1.3 License Restrictions. Customer shall not itself, or through any parent,
|
||||
subsidiary, affiliate, agent or other third party:
|
||||
1.3.1 sell, lease, license, distribute, sublicense or otherwise transfer
|
||||
in whole or in part, any Software or the Documentation to a third party;
|
||||
or
|
||||
1.3.2 decompile, disassemble, translate, reverse engineer or otherwise
|
||||
attempt to derive source code from the Software, in whole or in part, nor
|
||||
shall Customer use any mechanical, electronic or other method to trace,
|
||||
decompile, disassemble, or identify the source code of the Software or
|
||||
encourage others to do so, except to the limited extent, if any, that
|
||||
applicable law permits such acts notwithstanding any contractual
|
||||
prohibitions, provided, however, before Customer exercises any rights that
|
||||
Customer believes to be entitled to based on mandatory law, Customer shall
|
||||
provide StrongLoop with thirty (30) days prior written notice and provide
|
||||
all reasonably requested information to allow StrongLoop to assess
|
||||
Customer's claim and, at StrongLoop's sole discretion, to provide
|
||||
alternatives that reduce any adverse impact on StrongLoop's intellectual
|
||||
property or other rights; or
|
||||
1.3.3 allow access or permit use of the Software by any users other than
|
||||
Customer's employees or authorized third-party contractors who are
|
||||
providing services to Customer and agree in writing to abide by the terms
|
||||
of this Agreement, provided further that Customer shall be liable for any
|
||||
failure by such employees and third-party contractors to comply with the
|
||||
terms of this Agreement and no usage restrictions, if any, shall be
|
||||
exceeded; or
|
||||
1.3.4 create, develop, license, install, use, or deploy any third party
|
||||
software or services to circumvent or provide access, permissions or
|
||||
rights which violate the license keys embedded within the Software; or
|
||||
1.3.5 modify or create derivative works based upon the Software or
|
||||
Documentation; or disclose the results of any benchmark test of the
|
||||
Software to any third party without StrongLoop's prior written approval;
|
||||
or
|
||||
1.3.6 change any proprietary rights notices which appear in the Software
|
||||
or Documentation; or
|
||||
1.3.7 use the Software as part of a time sharing or service bureau
|
||||
purposes or in any other resale capacity.
|
||||
1.4 Third-Party Software. The Software may include individual certain software
|
||||
that is owned by third parties, including individual open source software
|
||||
components (the "Third-Party Software"), each of which has its own copyright and
|
||||
its own applicable license conditions. Such third-party software is licensed to
|
||||
Customer under the terms of the applicable third-party licenses and/or copyright
|
||||
notices that can be found in the LICENSES file, the Documentation or other
|
||||
materials accompanying the Software, except that Sections 5 (Warranty
|
||||
Disclaimer) and 6 (Limitation of Liability) also govern Customer's use of the
|
||||
third-party software. Customer agrees to comply with the terms and conditions
|
||||
of the relevant third-party software licenses.
|
||||
2. Support Services. StrongLoop has no obligation to provide any support for
|
||||
the Software other than the support services specifically described on the
|
||||
StrongLoop Site for the Subscription level procured by Customer. However,
|
||||
StrongLoop has endeavored to establish a community of users of the Software who
|
||||
have provided their own feedback, hints and advice regarding their experiences
|
||||
in using the Software. You can find that community and user feedback on the
|
||||
StrongLoop Site. The use of any information, content or other materials from,
|
||||
contained in or on the StrongLoop Site are subject to the StrongLoop website
|
||||
terms of use located here http://www.strongloop.com/terms-of-service.
|
||||
3. Confidentiality. For purposes of this Agreement, "Confidential Information"
|
||||
means any and all information or proprietary materials (in every form and media)
|
||||
not generally known in the relevant trade or industry and which has been or is
|
||||
hereafter disclosed or made available by StrongLoop to Customer in connection
|
||||
with the transactions contemplated under this Agreement, including (i) all trade
|
||||
secrets, (ii) existing or contemplated Software, services, designs, technology,
|
||||
processes, technical data, engineering, techniques, methodologies and concepts
|
||||
and any related information, and (iii) information relating to business plans,
|
||||
sales or marketing methods and customer lists or requirements. For a period of
|
||||
five (5) years from the date of disclosure of the applicable Confidential
|
||||
Information, Customer shall (i) hold the Confidential Information in trust and
|
||||
confidence and avoid the disclosure or release thereof to any other person or
|
||||
entity by using the same degree of care as it uses to avoid unauthorized use,
|
||||
disclosure, or dissemination of its own Confidential Information of a similar
|
||||
nature, but not less than reasonable care, and (ii) not use the Confidential
|
||||
Information for any purpose whatsoever except as expressly contemplated under
|
||||
this Agreement; provided that, to the extent the Confidential Information
|
||||
constitutes a trade secret under law, Customer agrees to protect such
|
||||
information for so long as it qualifies as a trade secret under applicable law.
|
||||
Customer shall disclose the Confidential Information only to those of its
|
||||
employees and contractors having a need to know such Confidential Information
|
||||
and shall take all reasonable precautions to ensure that such employees and
|
||||
contractors comply with the provisions of this Section. The obligations of
|
||||
Customer under this Section shall not apply to information that Customer can
|
||||
demonstrate (i) was in its possession at the time of disclosure and without
|
||||
restriction as to confidentiality, (ii) at the time of disclosure is generally
|
||||
available to the public or after disclosure becomes generally available to the
|
||||
public through no breach of agreement or other wrongful act by Customer, (iii)
|
||||
has been received from a third party without restriction on disclosure and
|
||||
without breach of agreement by Customer, or (iv) is independently developed by
|
||||
Customer without regard to the Confidential Information. In addition, Customer
|
||||
may disclose Confidential Information as required to comply with binding orders
|
||||
of governmental entities that have jurisdiction over it; provided that Customer
|
||||
gives StrongLoop reasonable written notice to allow StrongLoop to seek a
|
||||
protective order or other appropriate remedy, discloses only such Confidential
|
||||
Information as is required by the governmental entity, and uses commercially
|
||||
reasonable efforts to obtain confidential treatment for any Confidential
|
||||
Information disclosed. Notwithstanding the above, Customer agrees that
|
||||
StrongLoop, its employees and agents shall be free to use and employ their
|
||||
general skills, know-how, and expertise, and to use, disclose, and employ any
|
||||
generalized ideas, concepts, know-how, methods, techniques or skills gained or
|
||||
learned during the Term or thereafter.
|
||||
4. Ownership. StrongLoop shall retain all intellectual property and proprietary
|
||||
rights in the Software, Documentation, and related works, including but not
|
||||
limited to any derivative work of the foregoing and StrongLoop's licensors shall
|
||||
retain all intellectual property and proprietary rights in any Third-Party
|
||||
Software that may be provided with or as a part of the Software. Customer shall
|
||||
do nothing inconsistent with StrongLoop's or its licensors' title to the
|
||||
Software and the intellectual property rights embodied therein, including, but
|
||||
not limited to, transferring, loaning, selling, assigning, pledging, or
|
||||
otherwise disposing, encumbering, or suffering a lien or encumbrance upon or
|
||||
against any interest in the Software. The Software (including any Third-Party
|
||||
Software) contain copyrighted material, trade secrets and other proprietary
|
||||
material of StrongLoop and/or its licensors.
|
||||
5. Warranty Disclaimer. THE SOFTWARE (INCLUDING ANY THIRD-PARTY SOFTWARE) AND
|
||||
DOCUMENTATION MADE AVAILABLE TO CUSTOMER ARE PROVIDED "AS-IS" AND STRONGLOOP,
|
||||
ON BEHALF OF ITSELF AND ITS LICENSORS, EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE,
|
||||
PERFORMANCE, AND ACCURACY AND ANY IMPLIED WARRANTIES ARISING FROM STATUTE,
|
||||
COURSE OF DEALING, COURSE OF PERFORMANCE, OR USAGE OF TRADE. STRONGLOOP DOES
|
||||
NOT WARRANT THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR
|
||||
ERROR-FREE, THAT DEFECTS IN THE SOFTWARE WILL BE CORRECTED OR THAT THE SOFTWARE
|
||||
WILL PROVIDE OR ENSURE ANY PARTICULAR RESULTS OR OUTCOME. NO ORAL OR WRITTEN
|
||||
INFORMATION OR ADVICE GIVEN BY STRONGLOOP OR ITS AUTHORIZED REPRESENTATIVES
|
||||
SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE SCOPE OF THIS WARRANTY.
|
||||
STRONGLOOP IS NOT OBLIGATED TO PROVIDE CUSTOMER WITH UPGRADES TO THE SOFTWARE,
|
||||
BUT MAY ELECT TO DO SO IN ITS SOLE DISCRETION. SOME JURISDICTIONS DO NOT ALLOW
|
||||
THE EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT APPLY TO
|
||||
CUSTOMER.WITHOUT LIMITING THE GENERALITY OF THE FOREGOING DISCLAIMER, THE
|
||||
SOFTWARE AND DOCUMENTATION ARE NOT DESIGNED, MANUFACTURED OR INTENDED FOR USE IN
|
||||
THE PLANNING, CONSTRUCTION, MAINTENANCE, CONTROL, OR DIRECT OPERATION OF NUCLEAR
|
||||
FACILITIES, AIRCRAFT NAVIGATION, CONTROL OR COMMUNICATION SYSTEMS, WEAPONS
|
||||
SYSTEMS, OR DIRECT LIFE SUPPORT SYSTEMS.
|
||||
6. Limitation of Liability.
|
||||
6.1 Exclusion of Liability. IN NO EVENT WILL STRONGLOOP OR ITS LICENSORS
|
||||
BE LIABLE UNDER THIS AGREEMENT FOR ANY INDIRECT, RELIANCE, PUNITIVE,
|
||||
CONSEQUENTIAL, SPECIAL, EXEMPLARY, OR INCIDENTAL DAMAGES OF ANY KIND AND
|
||||
HOWEVER CAUSED (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
||||
BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION AND
|
||||
THE LIKE), EVEN IF STRONGLOOP HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES. CUSTOMER BEARS FULL RESPONSIBILITY FOR USE OF THE SOFTWARE AND
|
||||
THE SUBSCRIPTION AND STRONGLOOP DOES NOT GUARANTEE THAT THE USE OF THE
|
||||
SOFTWARE AND SUBSCRIPTION WILL ENSURE THAT CUSTOMER'S NETWORK WILL BE
|
||||
AVAILABLE, SECURE, MONITORED OR PROTECTED AGAINST ANY DOWNTIME, DENIAL OF
|
||||
SERVICE ATTACKS, SECUITY BREACHES, HACKERS AND THE LIKE. IN NO EVENT WILL
|
||||
STRONGLOOP'S CUMULATIVE LIABILITY FOR ANY DAMAGES, LOSSES AND CAUSES OF
|
||||
ACTION (WHETHER IN CONTRACT, TORT, INCLUDING NEGLIGENCE, OR OTHERWISE)
|
||||
ARISING OUT OF OR RELATED TO THIS AGREEMENT EXCEED THE GREATER OF ONE
|
||||
HUNDRED DOLLARS (US$100) OR THE TOTAL SUBSCRIPTION FEES PAID BY CUSTOMER
|
||||
TO STRONGLOOP IN THE TWELVE (12) MONTHS PRECEDING THE DATE THE CLAIM
|
||||
ARISES.
|
||||
6.2 Limitation of Damages. IN NO EVENT WILL STRONGLOOP'S LICENSORS HAVE
|
||||
ANY LIABILITY FOR ANY CLAIM ARISING IN CONNECTION WITH THIS AGREEMENT.
|
||||
THE PROVISIONS OF THIS SECTION 6 ALLOCATE RISKS UNDER THIS AGREEMENT
|
||||
BETWEEN CUSTOMER, STRONGLOOP AND STRONGLOOP'S SUPPLIERS. THE FOREGOING
|
||||
LIMITATIONS, EXCLUSIONS AND DISCLAIMERS APPLY TO THE MAXIMUM EXTENT
|
||||
PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS IN ITS ESSENTIAL
|
||||
PURPOSE.
|
||||
6.3 Failure of Essential Purpose. THE PARTIES AGREE THAT THESE
|
||||
LIMITATIONS SHALL APPLY EVEN IF THIS AGREEMENT OR ANY LIMITED REMEDY
|
||||
SPECIFIED HEREIN IS FOUND TO HAVE FAILED OF ITS ESSENTIAL PURPOSE.
|
||||
6.4 Allocation of Risk. The sections on limitation of liability and
|
||||
disclaimer of warranties allocate the risks in the Agreement between the
|
||||
parties. This allocation is an essential element of the basis of the
|
||||
bargain between the parties.
|
||||
7. Term and Termination.
|
||||
7.1 This Agreement shall commence on the Effective Date and continue for so long
|
||||
as Customer has a valid Subscription and is current on the payment of any
|
||||
Subscription Fees required to be paid for that Subscription (the "Subscription
|
||||
Term"). Either party may terminate this Agreement immediately upon written
|
||||
notice to the other party, and the Subscription and licenses granted hereunder
|
||||
automatically terminate upon the termination of this Agreement. This Agreement
|
||||
will terminate immediately without notice from StrongLoop if Customer fails to
|
||||
comply with or otherwise breaches any provision of this Agreement.
|
||||
7.2 All Sections other than Section 1.1 (Subscriptions) and 1.2 (Licenses) shall
|
||||
survive the expiration or termination of this Agreement.
|
||||
8. Subscription Fees and Payments. StrongLoop, Customer agrees to pay
|
||||
StrongLoop the Subscription Fees as described on the StrongLoop Site for the
|
||||
Subscription purchased unless a different amount has been agreed to in a
|
||||
separate agreement between Customer and StrongLoop. In addition, Customer shall
|
||||
pay all sales, use, value added, withholding, excise taxes and other tax, duty,
|
||||
custom and similar fees levied upon the delivery or use of the Software and the
|
||||
Subscriptions described in this Agreement. Fees shall be invoiced in full upon
|
||||
StrongLoop's acceptance of Customer's purchase order for the Subscription. All
|
||||
invoices shall be paid in US dollars and are due upon receipt and shall be paid
|
||||
within thirty (30) days. Payments shall be made without right of set-off or
|
||||
chargeback. If Customer does not pay the invoices when due, StrongLoop may
|
||||
charge interest at one percent (1%) per month or the highest rate permitted by
|
||||
law, whichever is lower, on the unpaid balance from the original due date. If
|
||||
Customer fails to pay fees in accordance with this Section, StrongLoop may
|
||||
suspend fulfilling its obligations under this Agreement (including but not
|
||||
limited to suspending the services under the Subscription) until payment is
|
||||
received by StrongLoop. If any applicable law requires Customer to withhold
|
||||
amounts from any payments to StrongLoop under this Agreement, (a) Customer shall
|
||||
effect such withholding, remit such amounts to the appropriate taxing
|
||||
authorities and promptly furnish StrongLoop with tax receipts evidencing the
|
||||
payments of such amounts and (b) the sum payable by Customer upon which the
|
||||
deduction or withholding is based shall be increased to the extent necessary to
|
||||
ensure that, after such deduction or withholding, StrongLoop receives and
|
||||
retains, free from liability for such deduction or withholding, a net amount
|
||||
equal to the amount StrongLoop would have received and retained absent the
|
||||
required deduction or withholding.
|
||||
9. General.
|
||||
9.1 Compliance with Laws. Customer shall abide by all local, state, federal and
|
||||
international laws, rules, regulations and orders applying to Customer's use of
|
||||
the Software, including, without limitation, the laws and regulations of the
|
||||
United States that may restrict the export and re-export of certain commodities
|
||||
and technical data of United States origin, including the Software. Customer
|
||||
agrees that it will not export or re-export the Software without the appropriate
|
||||
United States or foreign government licenses.
|
||||
9.2 Entire Agreement. This Agreement constitutes the entire agreement between
|
||||
the parties concerning the subject matter hereof. This Agreement supersedes all
|
||||
prior or contemporaneous discussions, proposals and agreements between the
|
||||
parties relating to the subject matter hereof. No amendment, modification or
|
||||
waiver of any provision of this Agreement shall be effective unless in writing
|
||||
and signed by both parties. Any additional or different terms on any purchase
|
||||
orders issued by Customer to StrongLoop shall not be binding on either party,
|
||||
are hereby rejected by StrongLoop and void.
|
||||
9.3 Severability. If any provision of this Agreement is held to be invalid or
|
||||
unenforceable, the remaining portions shall remain in full force and effect and
|
||||
such provision shall be enforced to the maximum extent possible so as to effect
|
||||
the intent of the parties and shall be reformed to the extent necessary to make
|
||||
such provision valid and enforceable.
|
||||
9.4 Waiver. No waiver of rights by either party may be implied from any actions
|
||||
or failures to enforce rights under this Agreement.
|
||||
9.5 Force Majeure. Neither party shall be liable to the other for any delay or
|
||||
failure to perform due to causes beyond its reasonable control (excluding
|
||||
payment of monies due).
|
||||
9.6 No Third Party Beneficiaries. Unless otherwise specifically stated, the
|
||||
terms of this Agreement are intended to be and are solely for the benefit of
|
||||
StrongLoop and Customer and do not create any right in favor of any third party.
|
||||
9.7 Governing Law and Jurisdiction. This Agreement shall be governed by the
|
||||
laws of the State of California, without reference to the principles of
|
||||
conflicts of law. The provisions of the Uniform Computerized Information
|
||||
Transaction Act and United Nations Convention on Contracts for the International
|
||||
Sale of Goods shall not apply to this Agreement. The parties shall attempt to
|
||||
resolve any dispute related to this Agreement informally, initially through
|
||||
their respective management, and then by non-binding mediation in San Francisco
|
||||
County, California. Any litigation related to this Agreement shall be brought
|
||||
in the state or federal courts located in San Francisco County, California, and
|
||||
only in those courts and each party irrevocably waives any objections to such
|
||||
venue.
|
||||
9.8 Notices. All notices must be in writing and shall be effective three (3)
|
||||
days after the date sent to the other party's headquarters, Attention Chief
|
||||
Financial Officer.
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
var jdb = require('../index');
|
||||
|
||||
var User, Post, Passport, City, Street, Building;
|
||||
var nbSchemaRequests = 0;
|
||||
|
||||
setup(function () {
|
||||
|
||||
Passport.find({include: 'owner'}, function (err, passports) {
|
||||
console.log('passports.owner', passports);
|
||||
});
|
||||
|
||||
User.find({include: 'posts'}, function (err, users) {
|
||||
console.log('users.posts', users);
|
||||
});
|
||||
|
||||
Passport.find({include: {owner: 'posts'}}, function (err, passports) {
|
||||
console.log('passports.owner.posts', passports);
|
||||
});
|
||||
|
||||
Passport.find({
|
||||
include: {owner: {posts: 'author'}}
|
||||
}, function (err, passports) {
|
||||
console.log('passports.owner.posts.author', passports);
|
||||
});
|
||||
|
||||
User.find({include: ['posts', 'passports']}, function (err, users) {
|
||||
console.log('users.passports && users.posts', users);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function setup(done) {
|
||||
var db = new jdb.DataSource({connector: 'memory'});
|
||||
City = db.define('City');
|
||||
Street = db.define('Street');
|
||||
Building = db.define('Building');
|
||||
User = db.define('User', {
|
||||
name: String,
|
||||
age: Number
|
||||
});
|
||||
Passport = db.define('Passport', {
|
||||
number: String
|
||||
});
|
||||
Post = db.define('Post', {
|
||||
title: String
|
||||
});
|
||||
|
||||
Passport.belongsTo('owner', {model: User});
|
||||
User.hasMany('passports', {foreignKey: 'ownerId'});
|
||||
User.hasMany('posts', {foreignKey: 'userId'});
|
||||
Post.belongsTo('author', {model: User, foreignKey: 'userId'});
|
||||
|
||||
db.automigrate(function () {
|
||||
var createdUsers = [];
|
||||
var createdPassports = [];
|
||||
var createdPosts = [];
|
||||
createUsers();
|
||||
function createUsers() {
|
||||
clearAndCreate(
|
||||
User,
|
||||
[
|
||||
{name: 'User A', age: 21},
|
||||
{name: 'User B', age: 22},
|
||||
{name: 'User C', age: 23},
|
||||
{name: 'User D', age: 24},
|
||||
{name: 'User E', age: 25}
|
||||
],
|
||||
function (items) {
|
||||
createdUsers = items;
|
||||
createPassports();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createPassports() {
|
||||
clearAndCreate(
|
||||
Passport,
|
||||
[
|
||||
{number: '1', ownerId: createdUsers[0].id},
|
||||
{number: '2', ownerId: createdUsers[1].id},
|
||||
{number: '3'}
|
||||
],
|
||||
function (items) {
|
||||
createdPassports = items;
|
||||
createPosts();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createPosts() {
|
||||
clearAndCreate(
|
||||
Post,
|
||||
[
|
||||
{title: 'Post A', userId: createdUsers[0].id},
|
||||
{title: 'Post B', userId: createdUsers[0].id},
|
||||
{title: 'Post C', userId: createdUsers[0].id},
|
||||
{title: 'Post D', userId: createdUsers[1].id},
|
||||
{title: 'Post E'}
|
||||
],
|
||||
function (items) {
|
||||
createdPosts = items;
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function clearAndCreate(model, data, callback) {
|
||||
var createdItems = [];
|
||||
model.destroyAll(function () {
|
||||
nextItem(null, null);
|
||||
});
|
||||
|
||||
var itemIndex = 0;
|
||||
|
||||
function nextItem(err, lastItem) {
|
||||
if (lastItem !== null) {
|
||||
createdItems.push(lastItem);
|
||||
}
|
||||
if (itemIndex >= data.length) {
|
||||
callback(createdItems);
|
||||
return;
|
||||
}
|
||||
model.create(data[itemIndex], nextItem);
|
||||
itemIndex++;
|
||||
}
|
||||
}
|
|
@ -29,4 +29,5 @@ var user = new User({name: 'Joe', age: 20, address: {street: '123 Main St', 'cit
|
|||
{label: 'work', email: 'xyz@sample.com'}
|
||||
],
|
||||
friends: ['John', 'Mary']});
|
||||
console.log(user);
|
||||
console.log(user.toObject());
|
||||
|
|
4
index.js
4
index.js
|
@ -1,5 +1,3 @@
|
|||
var fs = require('fs');
|
||||
|
||||
exports.ModelBuilder = exports.LDL = require('./lib/model-builder.js').ModelBuilder;
|
||||
exports.DataSource = exports.Schema = require('./lib/datasource.js').DataSource;
|
||||
exports.ModelBaseClass = require('./lib/model.js');
|
||||
|
@ -14,7 +12,7 @@ exports.__defineGetter__('BaseSQL', function () {
|
|||
|
||||
|
||||
exports.__defineGetter__('version', function () {
|
||||
return JSON.parse(fs.readFileSync(__dirname + '/package.json')).version;
|
||||
return require('./package.json').version;
|
||||
});
|
||||
|
||||
var commonTest = './test/common_test';
|
||||
|
|
13
lib/dao.js
13
lib/dao.js
|
@ -6,13 +6,12 @@ module.exports = DataAccessObject;
|
|||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
var util = require('util');
|
||||
var jutil = require('./jutil');
|
||||
var validations = require('./validations.js');
|
||||
var ValidationError = validations.ValidationError;
|
||||
require('./relations.js');
|
||||
var Inclusion = require('./include.js');
|
||||
var Relation = require('./relations.js');
|
||||
var Inclusion = require('./include.js');
|
||||
var List = require('./list.js');
|
||||
var geo = require('./geo');
|
||||
var Memory = require('./connectors/memory').Memory;
|
||||
var utils = require('./utils');
|
||||
|
@ -557,12 +556,16 @@ DataAccessObject.find = function find(params, cb) {
|
|||
var includes = params.include || [];
|
||||
if (typeof includes === 'string') {
|
||||
includes = [includes];
|
||||
} else if (typeof includes === 'object') {
|
||||
} else if (!Array.isArray(includes) && typeof includes === 'object') {
|
||||
includes = Object.keys(includes);
|
||||
}
|
||||
includes.forEach(function (inc) {
|
||||
// Promote the included model as a direct property
|
||||
obj.__data[inc] = obj.__cachedRelations[inc];
|
||||
var data = obj.__cachedRelations[inc];
|
||||
if(Array.isArray(data)) {
|
||||
data = new List(data, null, obj);
|
||||
}
|
||||
obj.__data[inc] = data;
|
||||
});
|
||||
delete obj.__data.__cachedRelations;
|
||||
}
|
||||
|
|
|
@ -7,11 +7,8 @@ var jutil = require('./jutil');
|
|||
var utils = require('./utils');
|
||||
var ModelBaseClass = require('./model.js');
|
||||
var DataAccessObject = require('./dao.js');
|
||||
var List = require('./list.js');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var assert = require('assert');
|
||||
var async = require('async');
|
||||
|
||||
|
@ -540,7 +537,7 @@ DataSource.prototype.mixin = function (ModelCtor) {
|
|||
var DAO = this.DataAccessObject;
|
||||
|
||||
// mixin DAO
|
||||
jutil.mixin(ModelCtor, DAO, {proxyFunctions: true});
|
||||
jutil.mixin(ModelCtor, DAO, {proxyFunctions: true, override: true});
|
||||
|
||||
// decorate operations as alias functions
|
||||
Object.keys(ops).forEach(function (name) {
|
||||
|
|
54
lib/jutil.js
54
lib/jutil.js
|
@ -55,39 +55,39 @@ exports.mixin = function (newClass, mixinClass, options) {
|
|||
}
|
||||
|
||||
if (options.staticProperties) {
|
||||
var staticProxies = [];
|
||||
Object.keys(mixinClass).forEach(function (classProp) {
|
||||
if (classProp !== 'super_' && classProp !== '_mixins'
|
||||
&& (!newClass.hasOwnProperty(classProp) || options.override)) {
|
||||
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
|
||||
if (options.proxyFunctions && pd.writable
|
||||
&& typeof pd.value === 'function') {
|
||||
pd.value = exports.proxy(pd.value, staticProxies);
|
||||
}
|
||||
Object.defineProperty(newClass, classProp, pd);
|
||||
}
|
||||
});
|
||||
mixInto(mixinClass, newClass, options);
|
||||
}
|
||||
|
||||
if (options.instanceProperties) {
|
||||
if (mixinClass.prototype) {
|
||||
var instanceProxies = [];
|
||||
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
|
||||
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
|
||||
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
|
||||
if (options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
|
||||
pd.value = exports.proxy(pd.value, instanceProxies);
|
||||
}
|
||||
Object.defineProperty(newClass.prototype, instanceProp, pd);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (options.instanceProperties && mixinClass.prototype) {
|
||||
mixInto(mixinClass.prototype, newClass.prototype, options);
|
||||
}
|
||||
|
||||
|
||||
return newClass;
|
||||
};
|
||||
|
||||
exports.proxy = function (fn, proxies) {
|
||||
function mixInto(sourceScope, targetScope, options) {
|
||||
var proxies = [];
|
||||
|
||||
Object.keys(sourceScope).forEach(function (propertyName, options) {
|
||||
var targetPropertyExists = targetScope.hasOwnProperty(propertyName);
|
||||
var sourceProperty = Object.getOwnPropertyDescriptor(sourceScope, propertyName);
|
||||
var targetProperty = targetPropertyExists && Object.getOwnPropertyDescriptor(targetScope, propertyName);
|
||||
var sourceIsFunc = typeof sourceProperty.value === 'function';
|
||||
var isFunc = targetPropertyExists && typeof targetProperty.value === 'function';
|
||||
var isDelegate = isFunc && targetProperty.value._delegate;
|
||||
var shouldOverride = options.override || !targetPropertyExists || isDelegate;
|
||||
|
||||
if (shouldOverride) {
|
||||
if (sourceIsFunc) {
|
||||
sourceProperty.value = exports.proxy(sourceProperty.value, proxies);
|
||||
}
|
||||
|
||||
Object.defineProperty(targetScope, propertyName, sourceProperty);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.proxy = function createProxy(fn, proxies) {
|
||||
// Make sure same methods referenced by different properties have the same proxy
|
||||
// For example, deleteById is an alias of removeById
|
||||
proxies = proxies || [];
|
||||
|
|
251
lib/list.js
251
lib/list.js
|
@ -1,154 +1,75 @@
|
|||
var util = require('util');
|
||||
|
||||
module.exports = List;
|
||||
|
||||
/**
|
||||
* List class provides functionality of nested collection
|
||||
*
|
||||
* @param {Array} data - array of items.
|
||||
* @param {Crap} type - array with some type information? TODO: rework this API.
|
||||
* @param {AbstractClass} parent - owner of list.
|
||||
* @constructor
|
||||
*/
|
||||
function List(data, type, parent) {
|
||||
function List(items, itemType, parent) {
|
||||
var list = this;
|
||||
if (!(list instanceof List)) {
|
||||
return new List(data, type, parent);
|
||||
return new List(items, itemType, parent);
|
||||
}
|
||||
|
||||
if (typeof data === 'string') {
|
||||
if (typeof items === 'string') {
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
items = JSON.parse(items);
|
||||
} catch (e) {
|
||||
throw new Error('could not create List from JSON string: ', data);
|
||||
throw new Error('could not create List from JSON string: ', items);
|
||||
}
|
||||
}
|
||||
|
||||
if (data && data instanceof List) data = data.items;
|
||||
var arr = [];
|
||||
arr.__proto__ = List.prototype;
|
||||
|
||||
Object.defineProperty(list, 'parent', {
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
value: parent
|
||||
});
|
||||
items = items || [];
|
||||
if (!Array.isArray(items)) {
|
||||
throw new Error('Items must be an array: ' + items);
|
||||
}
|
||||
|
||||
Object.defineProperty(list, 'nextid', {
|
||||
if(!itemType) {
|
||||
itemType = items[0] && items[0].constructor;
|
||||
}
|
||||
|
||||
if (Array.isArray(itemType)) {
|
||||
itemType = itemType[0];
|
||||
}
|
||||
|
||||
Object.defineProperty(arr, 'itemType', {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
value: 1
|
||||
value: itemType
|
||||
});
|
||||
|
||||
data = list.items = data || [];
|
||||
var Item = list.ItemType = ListItem;
|
||||
|
||||
if (typeof type === 'object' && type.constructor.name === 'Array') {
|
||||
Item = list.ItemType = type[0] || ListItem;
|
||||
}
|
||||
|
||||
data.forEach(function (item, i) {
|
||||
data[i] = Item(item, list);
|
||||
Object.defineProperty(list, data[i].id, {
|
||||
if (parent) {
|
||||
Object.defineProperty(arr, 'parent', {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: data[i]
|
||||
value: parent
|
||||
});
|
||||
if (list.nextid <= data[i].id) {
|
||||
list.nextid = data[i].id + 1;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(list, 'length', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
get: function () {
|
||||
return list.items.length;
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
var _;
|
||||
try {
|
||||
var underscore = 'underscore';
|
||||
_ = require(underscore);
|
||||
} catch (e) {
|
||||
_ = false;
|
||||
}
|
||||
|
||||
if (_) {
|
||||
var _import = [
|
||||
// collection methods
|
||||
'each',
|
||||
'map',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'find',
|
||||
'filter',
|
||||
'reject',
|
||||
'all',
|
||||
'any',
|
||||
'include',
|
||||
'invoke',
|
||||
'pluck',
|
||||
'max',
|
||||
'min',
|
||||
'sortBy',
|
||||
'groupBy',
|
||||
'sortedIndex',
|
||||
'shuffle',
|
||||
'toArray',
|
||||
'size',
|
||||
// array methods
|
||||
'first',
|
||||
'initial',
|
||||
'last',
|
||||
'rest',
|
||||
'compact',
|
||||
'flatten',
|
||||
'without',
|
||||
'union',
|
||||
'intersection',
|
||||
'difference',
|
||||
'uniq',
|
||||
'zip',
|
||||
'indexOf',
|
||||
'lastIndexOf',
|
||||
'range'
|
||||
];
|
||||
|
||||
_import.forEach(function (name) {
|
||||
List.prototype[name] = function () {
|
||||
var args = [].slice.call(arguments);
|
||||
args.unshift(this.items);
|
||||
return _[name].apply(_, args);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
['slice', 'forEach', 'filter', 'reduce', 'map'].forEach(function (method) {
|
||||
var slice = [].slice;
|
||||
List.prototype[method] = function () {
|
||||
return Array.prototype[method].apply(this.items, slice.call(arguments));
|
||||
};
|
||||
});
|
||||
|
||||
List.prototype.find = function (pattern, field) {
|
||||
if (field) {
|
||||
var res;
|
||||
this.items.forEach(function (o) {
|
||||
if (o[field] == pattern) res = o;
|
||||
});
|
||||
return res;
|
||||
} else {
|
||||
return this.items[this.items.indexOf(pattern)];
|
||||
}
|
||||
|
||||
items.forEach(function (item, i) {
|
||||
if (itemType && !(item instanceof itemType)) {
|
||||
arr[i] = itemType(item);
|
||||
} else {
|
||||
arr[i] = item;
|
||||
}
|
||||
});
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
util.inherits(List, Array);
|
||||
|
||||
var _push = List.prototype.push;
|
||||
|
||||
List.prototype.push = function (obj) {
|
||||
var item = this.itemType && (obj instanceof this.itemType) ? obj : this.itemType(obj);
|
||||
_push.call(this, item);
|
||||
return item;
|
||||
};
|
||||
|
||||
List.prototype.toObject = function (onlySchema) {
|
||||
var items = [];
|
||||
this.items.forEach(function (item) {
|
||||
this.forEach(function (item) {
|
||||
if (item.toObject) {
|
||||
items.push(item.toObject(onlySchema));
|
||||
} else {
|
||||
|
@ -163,75 +84,15 @@ List.prototype.toJSON = function () {
|
|||
};
|
||||
|
||||
List.prototype.toString = function () {
|
||||
return JSON.stringify(this.items);
|
||||
return JSON.stringify(this.toJSON());
|
||||
};
|
||||
|
||||
List.prototype.autoincrement = function () {
|
||||
return this.nextid++;
|
||||
};
|
||||
|
||||
List.prototype.push = function (obj) {
|
||||
var item = new ListItem(obj, this);
|
||||
this.items.push(item);
|
||||
return item;
|
||||
};
|
||||
|
||||
List.prototype.remove = function (obj) {
|
||||
var id = obj.id ? obj.id : obj;
|
||||
var found = false;
|
||||
this.items.forEach(function (o, i) {
|
||||
if (id && o.id == id) {
|
||||
found = i;
|
||||
if (o.id !== id) {
|
||||
console.log('WARNING! Type of id not matched');
|
||||
}
|
||||
}
|
||||
});
|
||||
if (found !== false) {
|
||||
delete this[id];
|
||||
this.items.splice(found, 1);
|
||||
}
|
||||
};
|
||||
|
||||
List.prototype.sort = function (cb) {
|
||||
return this.items.sort(cb);
|
||||
};
|
||||
|
||||
List.prototype.map = function (cb) {
|
||||
if (typeof cb === 'function') return this.items.map(cb);
|
||||
if (typeof cb === 'string') return this.items.map(function (el) {
|
||||
if (typeof el[cb] === 'function') return el[cb]();
|
||||
if (el.hasOwnProperty(cb)) return el[cb];
|
||||
});
|
||||
};
|
||||
|
||||
function ListItem(data, parent) {
|
||||
if (!(this instanceof ListItem)) {
|
||||
return new ListItem(data, parent);
|
||||
}
|
||||
if (typeof data === 'object') {
|
||||
for (var i in data) this[i] = data[i];
|
||||
} else {
|
||||
this.id = data;
|
||||
}
|
||||
Object.defineProperty(this, 'parent', {
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: parent
|
||||
});
|
||||
if (!this.id) {
|
||||
this.id = parent.autoincrement();
|
||||
}
|
||||
if (parent.ItemType) {
|
||||
this.__proto__ = parent.ItemType.prototype;
|
||||
if (parent.ItemType !== ListItem) {
|
||||
parent.ItemType.apply(this);
|
||||
}
|
||||
}
|
||||
|
||||
this.save = function (c) {
|
||||
parent.parent.save(c);
|
||||
};
|
||||
}
|
||||
/*
|
||||
var strArray = new List(['1', 2], String);
|
||||
strArray.push(3);
|
||||
console.log(strArray);
|
||||
console.log(strArray.length);
|
||||
|
||||
console.log(strArray.toJSON());
|
||||
console.log(strArray.toString());
|
||||
*/
|
||||
|
|
104
lib/types.js
104
lib/types.js
|
@ -1,44 +1,48 @@
|
|||
module.exports = function (Types) {
|
||||
var Types = {};
|
||||
/**
|
||||
* Schema types
|
||||
*/
|
||||
Types.Text = function Text(value) {
|
||||
if (!(this instanceof Text)) {
|
||||
return value;
|
||||
}
|
||||
this.value = value;
|
||||
}; // Text type
|
||||
|
||||
Types.Text.prototype.toObject = Types.Text.prototype.toJSON = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
Types.JSON = function JSON(value) {
|
||||
if (!(this instanceof JSON)) {
|
||||
return value;
|
||||
}
|
||||
this.value = value;
|
||||
}; // JSON Object
|
||||
Types.JSON.prototype.toObject = Types.JSON.prototype.toJSON = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
Types.Any = function Any(value) {
|
||||
if (!(this instanceof Any)) {
|
||||
return value;
|
||||
}
|
||||
this.value = value;
|
||||
}; // Any Type
|
||||
Types.Any.prototype.toObject = Types.Any.prototype.toJSON = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
module.exports = function (modelTypes) {
|
||||
|
||||
var List = require('./list.js');
|
||||
var GeoPoint = require('./geo').GeoPoint;
|
||||
|
||||
/**
|
||||
* Schema types
|
||||
*/
|
||||
Types.Text = function Text(value) {
|
||||
if (!(this instanceof Text)) {
|
||||
return value;
|
||||
}
|
||||
this.value = value;
|
||||
}; // Text type
|
||||
for(var t in Types) {
|
||||
modelTypes[t] = Types[t];
|
||||
}
|
||||
|
||||
Types.Text.prototype.toObject = Types.Text.prototype.toJSON = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
Types.JSON = function JSON(value) {
|
||||
if (!(this instanceof JSON)) {
|
||||
return value;
|
||||
}
|
||||
this.value = value;
|
||||
}; // JSON Object
|
||||
Types.JSON.prototype.toObject = Types.JSON.prototype.toJSON = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
Types.Any = function Any(value) {
|
||||
if (!(this instanceof Any)) {
|
||||
return value;
|
||||
}
|
||||
this.value = value;
|
||||
}; // Any Type
|
||||
Types.Any.prototype.toObject = Types.Any.prototype.toJSON = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
Types.schemaTypes = {};
|
||||
Types.registerType = function (type, names) {
|
||||
modelTypes.schemaTypes = {};
|
||||
modelTypes.registerType = function (type, names) {
|
||||
names = names || [];
|
||||
names = names.concat([type.name]);
|
||||
for (var n = 0; n < names.length; n++) {
|
||||
|
@ -46,16 +50,18 @@ module.exports = function (Types) {
|
|||
}
|
||||
};
|
||||
|
||||
Types.registerType(Types.Text);
|
||||
Types.registerType(Types.JSON);
|
||||
Types.registerType(Types.Any);
|
||||
modelTypes.registerType(Types.Text);
|
||||
modelTypes.registerType(Types.JSON);
|
||||
modelTypes.registerType(Types.Any);
|
||||
|
||||
Types.registerType(String);
|
||||
Types.registerType(Number);
|
||||
Types.registerType(Boolean);
|
||||
Types.registerType(Date);
|
||||
Types.registerType(Buffer, ['Binary']);
|
||||
Types.registerType(Array);
|
||||
Types.registerType(GeoPoint);
|
||||
Types.registerType(Object);
|
||||
};
|
||||
modelTypes.registerType(String);
|
||||
modelTypes.registerType(Number);
|
||||
modelTypes.registerType(Boolean);
|
||||
modelTypes.registerType(Date);
|
||||
modelTypes.registerType(Buffer, ['Binary']);
|
||||
modelTypes.registerType(Array);
|
||||
modelTypes.registerType(GeoPoint);
|
||||
modelTypes.registerType(Object);
|
||||
};
|
||||
|
||||
module.exports.Types = Types;
|
11
package.json
11
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "loopback-datasource-juggler",
|
||||
"version": "1.3.2",
|
||||
"version": "1.3.3",
|
||||
"description": "LoopBack DataSoure Juggler",
|
||||
"keywords": [
|
||||
"StrongLoop",
|
||||
|
@ -24,13 +24,16 @@
|
|||
],
|
||||
"devDependencies": {
|
||||
"should": "~1.2.2",
|
||||
"mocha": "~1.12.1"
|
||||
"mocha": "~1.17.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.10",
|
||||
"inflection": "~1.2.7",
|
||||
"inflection": "~1.3.5",
|
||||
"traverse": "~0.6.6",
|
||||
"qs": "~0.6.6"
|
||||
},
|
||||
"license": "MIT"
|
||||
"license": {
|
||||
"name": "Dual MIT/StrongLoop",
|
||||
"url": "https://github.com/strongloop/loopback-datasource-juggler/blob/master/LICENSE"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,8 +117,15 @@ describe('include', function () {
|
|||
// The relation should be promoted as the 'owner' property
|
||||
user.should.have.property('posts');
|
||||
user.should.have.property('passports');
|
||||
|
||||
var userObj = user.toJSON();
|
||||
userObj.should.have.property('posts');
|
||||
userObj.should.have.property('passports');
|
||||
userObj.posts.should.be.an.instanceOf(Array);
|
||||
userObj.passports.should.be.an.instanceOf(Array);
|
||||
|
||||
// The __cachedRelations should be removed from json output
|
||||
user.toJSON().should.not.have.property('__cachedRelations');
|
||||
userObj.should.not.have.property('__cachedRelations');
|
||||
|
||||
user.__cachedRelations.should.have.property('posts');
|
||||
user.__cachedRelations.should.have.property('passports');
|
||||
|
|
Loading…
Reference in New Issue