Merge branch 'release/1.7.0' into production
This commit is contained in:
commit
7332b3deb9
|
@ -0,0 +1,154 @@
|
||||||
|
/*global module:false*/
|
||||||
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
// Metadata.
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
|
||||||
|
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
||||||
|
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
|
||||||
|
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
|
||||||
|
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
|
||||||
|
// Task configuration.
|
||||||
|
uglify: {
|
||||||
|
options: {
|
||||||
|
banner: '<%= banner %>'
|
||||||
|
},
|
||||||
|
dist: {
|
||||||
|
files: {
|
||||||
|
'dist/loopback.min.js': ['dist/loopback.js']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jshint: {
|
||||||
|
options: {
|
||||||
|
jshintrc: true
|
||||||
|
},
|
||||||
|
gruntfile: {
|
||||||
|
src: 'Gruntfile.js'
|
||||||
|
},
|
||||||
|
lib_test: {
|
||||||
|
src: ['lib/**/*.js', 'test/**/*.js']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
gruntfile: {
|
||||||
|
files: '<%= jshint.gruntfile.src %>',
|
||||||
|
tasks: ['jshint:gruntfile']
|
||||||
|
},
|
||||||
|
lib_test: {
|
||||||
|
files: '<%= jshint.lib_test.src %>',
|
||||||
|
tasks: ['jshint:lib_test']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
browserify: {
|
||||||
|
dist: {
|
||||||
|
files: {
|
||||||
|
'dist/loopback.js': ['index.js'],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
ignore: ['nodemailer', 'passport'],
|
||||||
|
standalone: 'loopback'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
karma: {
|
||||||
|
unit: {
|
||||||
|
options: {
|
||||||
|
// base path, that will be used to resolve files and exclude
|
||||||
|
basePath: '',
|
||||||
|
|
||||||
|
// frameworks to use
|
||||||
|
frameworks: ['mocha', 'browserify'],
|
||||||
|
|
||||||
|
// list of files / patterns to load in the browser
|
||||||
|
files: [
|
||||||
|
'test/support.js',
|
||||||
|
'test/model.test.js',
|
||||||
|
'test/geo-point.test.js'
|
||||||
|
],
|
||||||
|
|
||||||
|
// list of files to exclude
|
||||||
|
exclude: [
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
// test results reporter to use
|
||||||
|
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
||||||
|
reporters: ['dots'],
|
||||||
|
|
||||||
|
// web server port
|
||||||
|
port: 9876,
|
||||||
|
|
||||||
|
// cli runner port
|
||||||
|
runnerPort: 9100,
|
||||||
|
|
||||||
|
// enable / disable colors in the output (reporters and logs)
|
||||||
|
colors: true,
|
||||||
|
|
||||||
|
// level of logging
|
||||||
|
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||||
|
logLevel: 'warn',
|
||||||
|
|
||||||
|
// enable / disable watching file and executing tests whenever any file changes
|
||||||
|
autoWatch: true,
|
||||||
|
|
||||||
|
// Start these browsers, currently available:
|
||||||
|
// - Chrome
|
||||||
|
// - ChromeCanary
|
||||||
|
// - Firefox
|
||||||
|
// - Opera
|
||||||
|
// - Safari (only Mac)
|
||||||
|
// - PhantomJS
|
||||||
|
// - IE (only Windows)
|
||||||
|
browsers: [
|
||||||
|
'Chrome',
|
||||||
|
'Firefox',
|
||||||
|
'Opera',
|
||||||
|
'Safari',
|
||||||
|
'PhantomJS'
|
||||||
|
],
|
||||||
|
|
||||||
|
// If browser does not capture in given timeout [ms], kill it
|
||||||
|
captureTimeout: 60000,
|
||||||
|
|
||||||
|
// Continuous Integration mode
|
||||||
|
// if true, it capture browsers, run tests and exit
|
||||||
|
singleRun: false,
|
||||||
|
|
||||||
|
// Browserify config (all optional)
|
||||||
|
browserify: {
|
||||||
|
// extensions: ['.coffee'],
|
||||||
|
ignore: [
|
||||||
|
'nodemailer',
|
||||||
|
'passport',
|
||||||
|
'passport-local',
|
||||||
|
'superagent',
|
||||||
|
'supertest'
|
||||||
|
],
|
||||||
|
// transform: ['coffeeify'],
|
||||||
|
// debug: true,
|
||||||
|
// noParse: ['jquery'],
|
||||||
|
watch: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Add browserify to preprocessors
|
||||||
|
preprocessors: {'test/*': ['browserify']}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// These plugins provide necessary tasks.
|
||||||
|
grunt.loadNpmTasks('grunt-browserify');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
|
grunt.loadNpmTasks('grunt-karma');
|
||||||
|
|
||||||
|
// Default task.
|
||||||
|
grunt.registerTask('default', ['browserify']);
|
||||||
|
|
||||||
|
};
|
294
LICENSE
294
LICENSE
|
@ -1,4 +1,10 @@
|
||||||
Copyright (c) 2013 StrongLoop, Inc.
|
Copyright (c) 2013-2014 StrongLoop, Inc.
|
||||||
|
|
||||||
|
loopback uses a 'dual license' model. Users may use loopback 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
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.
|
||||||
|
|
|
@ -7,6 +7,7 @@ var DataSource = require('loopback-datasource-juggler').DataSource
|
||||||
, compat = require('./compat')
|
, compat = require('./compat')
|
||||||
, assert = require('assert')
|
, assert = require('assert')
|
||||||
, fs = require('fs')
|
, fs = require('fs')
|
||||||
|
, _ = require('underscore')
|
||||||
, RemoteObjects = require('strong-remoting')
|
, RemoteObjects = require('strong-remoting')
|
||||||
, swagger = require('strong-remoting/ext/swagger')
|
, swagger = require('strong-remoting/ext/swagger')
|
||||||
, stringUtils = require('underscore.string')
|
, stringUtils = require('underscore.string')
|
||||||
|
@ -56,7 +57,8 @@ app.remotes = function () {
|
||||||
if(this._remotes) {
|
if(this._remotes) {
|
||||||
return this._remotes;
|
return this._remotes;
|
||||||
} else {
|
} else {
|
||||||
return (this._remotes = RemoteObjects.create());
|
var options = this.get('remoting') || {};
|
||||||
|
return (this._remotes = RemoteObjects.create(options));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ app.model = function (Model, config) {
|
||||||
var remotingClassName = compat.getClassNameForRemoting(Model);
|
var remotingClassName = compat.getClassNameForRemoting(Model);
|
||||||
this.remotes().exports[remotingClassName] = Model;
|
this.remotes().exports[remotingClassName] = Model;
|
||||||
this.models().push(Model);
|
this.models().push(Model);
|
||||||
|
clearHandlerCache(this);
|
||||||
Model.shared = true;
|
Model.shared = true;
|
||||||
Model.app = this;
|
Model.app = this;
|
||||||
Model.emit('attached', this);
|
Model.emit('attached', this);
|
||||||
|
@ -212,14 +215,6 @@ app.remoteObjects = function () {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the apps set of remote objects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
app.remotes = function () {
|
|
||||||
return this._remotes || (this._remotes = RemoteObjects.create());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable swagger REST API documentation.
|
* Enable swagger REST API documentation.
|
||||||
*
|
*
|
||||||
|
@ -431,15 +426,16 @@ app.boot = function(options) {
|
||||||
process.env.npm_package_config_host ||
|
process.env.npm_package_config_host ||
|
||||||
app.get('host');
|
app.get('host');
|
||||||
|
|
||||||
appConfig.port =
|
appConfig.port = _.find([
|
||||||
process.env.npm_config_port ||
|
process.env.npm_config_port,
|
||||||
process.env.OPENSHIFT_SLS_PORT ||
|
process.env.OPENSHIFT_SLS_PORT,
|
||||||
process.env.OPENSHIFT_NODEJS_PORT ||
|
process.env.OPENSHIFT_NODEJS_PORT,
|
||||||
process.env.PORT ||
|
process.env.PORT,
|
||||||
appConfig.port ||
|
appConfig.port,
|
||||||
process.env.npm_package_config_port ||
|
process.env.npm_package_config_port,
|
||||||
app.get('port') ||
|
app.get('port'),
|
||||||
3000;
|
3000
|
||||||
|
], _.isFinite);
|
||||||
|
|
||||||
appConfig.restApiRoot =
|
appConfig.restApiRoot =
|
||||||
appConfig.restApiRoot ||
|
appConfig.restApiRoot ||
|
||||||
|
@ -639,6 +635,10 @@ function tryReadConfig(cwd, fileName) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearHandlerCache(app) {
|
||||||
|
app._handlers = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install all express middleware required by LoopBack.
|
* Install all express middleware required by LoopBack.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = browserExpress;
|
||||||
|
|
||||||
|
function browserExpress() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
browserExpress.errorHandler = {};
|
|
@ -5,6 +5,7 @@
|
||||||
var mailer = require('nodemailer')
|
var mailer = require('nodemailer')
|
||||||
, assert = require('assert')
|
, assert = require('assert')
|
||||||
, debug = require('debug')
|
, debug = require('debug')
|
||||||
|
, loopback = require('../loopback')
|
||||||
, STUB = 'STUB';
|
, STUB = 'STUB';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +24,9 @@ function MailConnector(settings) {
|
||||||
this.transportsIndex = {};
|
this.transportsIndex = {};
|
||||||
this.transports = [];
|
this.transports = [];
|
||||||
|
|
||||||
transports.forEach(this.setupTransport.bind(this));
|
if(loopback.isServer) {
|
||||||
|
transports.forEach(this.setupTransport.bind(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MailConnector.initialize = function(dataSource, callback) {
|
MailConnector.initialize = function(dataSource, callback) {
|
||||||
|
|
|
@ -8,11 +8,11 @@ var express = require('express')
|
||||||
, EventEmitter = require('events').EventEmitter
|
, EventEmitter = require('events').EventEmitter
|
||||||
, path = require('path')
|
, path = require('path')
|
||||||
, proto = require('./application')
|
, proto = require('./application')
|
||||||
, utils = require('express/node_modules/connect').utils
|
|
||||||
, DataSource = require('loopback-datasource-juggler').DataSource
|
, DataSource = require('loopback-datasource-juggler').DataSource
|
||||||
, ModelBuilder = require('loopback-datasource-juggler').ModelBuilder
|
, ModelBuilder = require('loopback-datasource-juggler').ModelBuilder
|
||||||
, assert = require('assert')
|
, i8n = require('inflection')
|
||||||
, i8n = require('inflection');
|
, merge = require('util')._extend
|
||||||
|
, assert = require('assert');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `loopback` is the main entry for LoopBack core module. It provides static
|
* `loopback` is the main entry for LoopBack core module. It provides static
|
||||||
|
@ -28,6 +28,18 @@ var express = require('express')
|
||||||
|
|
||||||
var loopback = exports = module.exports = createApplication;
|
var loopback = exports = module.exports = createApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a browser environment?
|
||||||
|
*/
|
||||||
|
|
||||||
|
loopback.isBrowser = typeof window !== 'undefined';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a server environment?
|
||||||
|
*/
|
||||||
|
|
||||||
|
loopback.isServer = !loopback.isBrowser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Framework version.
|
* Framework version.
|
||||||
*/
|
*/
|
||||||
|
@ -55,7 +67,7 @@ loopback.compat = require('./compat');
|
||||||
function createApplication() {
|
function createApplication() {
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
utils.merge(app, proto);
|
merge(app, proto);
|
||||||
|
|
||||||
// Create a new instance of models registry per each app instance
|
// Create a new instance of models registry per each app instance
|
||||||
app.models = function() {
|
app.models = function() {
|
||||||
|
@ -80,16 +92,20 @@ for (var key in express) {
|
||||||
/*!
|
/*!
|
||||||
* Expose additional loopback middleware
|
* Expose additional loopback middleware
|
||||||
* for example `loopback.configure` etc.
|
* for example `loopback.configure` etc.
|
||||||
|
*
|
||||||
|
* ***only in node***
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fs
|
if (loopback.isServer) {
|
||||||
.readdirSync(path.join(__dirname, 'middleware'))
|
fs
|
||||||
.filter(function (file) {
|
.readdirSync(path.join(__dirname, 'middleware'))
|
||||||
return file.match(/\.js$/);
|
.filter(function (file) {
|
||||||
})
|
return file.match(/\.js$/);
|
||||||
.forEach(function (m) {
|
})
|
||||||
loopback[m.replace(/\.js$/, '')] = require('./middleware/' + m);
|
.forEach(function (m) {
|
||||||
});
|
loopback[m.replace(/\.js$/, '')] = require('./middleware/' + m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Error handler title
|
* Error handler title
|
||||||
|
@ -148,7 +164,7 @@ loopback.createModel = function (name, properties, options) {
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a remote method to a model.
|
* Add a remote method to a model.
|
||||||
|
@ -164,7 +180,7 @@ loopback.remoteMethod = function (fn, options) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn.http = fn.http || {verb: 'get'};
|
fn.http = fn.http || {verb: 'get'};
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a template helper.
|
* Create a template helper.
|
||||||
|
@ -180,7 +196,7 @@ loopback.template = function (file) {
|
||||||
var templates = this._templates || (this._templates = {});
|
var templates = this._templates || (this._templates = {});
|
||||||
var str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8'));
|
var str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8'));
|
||||||
return ejs.compile(str);
|
return ejs.compile(str);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an in-memory data source. Use one if it already exists.
|
* Get an in-memory data source. Use one if it already exists.
|
||||||
|
@ -202,7 +218,7 @@ loopback.memory = function (name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return memory;
|
return memory;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a model class by name from all models created by loopback.createModel()
|
* Look up a model class by name from all models created by loopback.createModel()
|
||||||
|
@ -246,7 +262,7 @@ loopback.setDefaultDataSourceForType = function(type, dataSource) {
|
||||||
|
|
||||||
defaultDataSources[type] = dataSource;
|
defaultDataSources[type] = dataSource;
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default `dataSource` for a given `type`.
|
* Get the default `dataSource` for a given `type`.
|
||||||
|
@ -256,7 +272,7 @@ loopback.setDefaultDataSourceForType = function(type, dataSource) {
|
||||||
|
|
||||||
loopback.getDefaultDataSourceForType = function(type) {
|
loopback.getDefaultDataSourceForType = function(type) {
|
||||||
return this.defaultDataSources && this.defaultDataSources[type];
|
return this.defaultDataSources && this.defaultDataSources[type];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach any model that does not have a dataSource to
|
* Attach any model that does not have a dataSource to
|
||||||
|
@ -275,7 +291,7 @@ loopback.autoAttach = function() {
|
||||||
loopback.autoAttachModel(ModelCtor);
|
loopback.autoAttachModel(ModelCtor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
loopback.autoAttachModel = function(ModelCtor) {
|
loopback.autoAttachModel = function(ModelCtor) {
|
||||||
if(ModelCtor.autoAttach) {
|
if(ModelCtor.autoAttach) {
|
||||||
|
@ -287,7 +303,7 @@ loopback.autoAttachModel = function(ModelCtor) {
|
||||||
|
|
||||||
ModelCtor.attachTo(ds);
|
ModelCtor.attachTo(ds);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Built in models / services
|
* Built in models / services
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var loopback = require('../loopback');
|
var loopback = require('../loopback');
|
||||||
var RemoteObjects = require('strong-remoting');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export the middleware.
|
* Export the middleware.
|
||||||
|
@ -23,7 +22,7 @@ function rest() {
|
||||||
if(req.url === '/routes') {
|
if(req.url === '/routes') {
|
||||||
res.send(handler.adapter.allRoutes());
|
res.send(handler.adapter.allRoutes());
|
||||||
} else if(req.url === '/models') {
|
} else if(req.url === '/models') {
|
||||||
return res.send(remotes.toJSON());
|
return res.send(app.remotes().toJSON());
|
||||||
} else {
|
} else {
|
||||||
handler(req, res, next);
|
handler(req, res, next);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var loopback = require('../loopback');
|
var loopback = require('../loopback');
|
||||||
var RemoteObjects = require('strong-remoting');
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -53,7 +53,14 @@ var AccessToken = module.exports = Model.extend('AccessToken', properties, {
|
||||||
property: 'create',
|
property: 'create',
|
||||||
permission: 'ALLOW'
|
permission: 'ALLOW'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
relations: {
|
||||||
|
user: {
|
||||||
|
type: 'belongsTo',
|
||||||
|
model: 'User',
|
||||||
|
foreignKey: 'userId'
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,7 +53,7 @@ var options = {
|
||||||
{
|
{
|
||||||
principalType: ACL.ROLE,
|
principalType: ACL.ROLE,
|
||||||
principalId: Role.EVERYONE,
|
principalId: Role.EVERYONE,
|
||||||
permission: ACL.DENY,
|
permission: ACL.DENY
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
principalType: ACL.ROLE,
|
principalType: ACL.ROLE,
|
||||||
|
@ -91,7 +91,14 @@ var options = {
|
||||||
permission: ACL.ALLOW,
|
permission: ACL.ALLOW,
|
||||||
property: "updateAttributes"
|
property: "updateAttributes"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
relations: {
|
||||||
|
accessTokens: {
|
||||||
|
type: 'hasMany',
|
||||||
|
model: 'AccessToken',
|
||||||
|
foreignKey: 'userId'
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,7 +189,7 @@ User.login = function (credentials, include, fn) {
|
||||||
fn(defaultError);
|
fn(defaultError);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logout a user with the given accessToken id.
|
* Logout a user with the given accessToken id.
|
||||||
|
|
40
package.json
40
package.json
|
@ -9,39 +9,63 @@
|
||||||
"Platform",
|
"Platform",
|
||||||
"mBaaS"
|
"mBaaS"
|
||||||
],
|
],
|
||||||
"version": "1.6.2",
|
"version": "1.7.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha -R spec"
|
"test": "mocha -R spec"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "~0.7.4",
|
"debug": "~0.7.4",
|
||||||
"express": "~3.4.8",
|
"express": "~3.4.8",
|
||||||
"strong-remoting": "~1.2.4",
|
"strong-remoting": "~1.2.6",
|
||||||
"inflection": "~1.2.7",
|
"inflection": "~1.3.5",
|
||||||
"passport": "~0.2.0",
|
"passport": "~0.2.0",
|
||||||
"passport-local": "~0.1.6",
|
"passport-local": "~0.1.6",
|
||||||
"nodemailer": "~0.6.0",
|
"nodemailer": "~0.6.0",
|
||||||
"ejs": "~0.8.5",
|
"ejs": "~0.8.5",
|
||||||
"bcryptjs": "~0.7.10",
|
"bcryptjs": "~0.7.12",
|
||||||
"underscore.string": "~2.3.3",
|
"underscore.string": "~2.3.3",
|
||||||
"underscore": "~1.6.0",
|
"underscore": "~1.6.0",
|
||||||
"uid2": "0.0.3",
|
"uid2": "0.0.3",
|
||||||
"async": "~0.2.10"
|
"async": "~0.2.10"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"loopback-datasource-juggler": "~1.3.0"
|
"loopback-datasource-juggler": "~1.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"loopback-datasource-juggler": "~1.3.0",
|
"loopback-datasource-juggler": "~1.3.3",
|
||||||
"mocha": "~1.17.1",
|
"mocha": "~1.17.1",
|
||||||
"strong-task-emitter": "0.0.x",
|
"strong-task-emitter": "0.0.x",
|
||||||
"supertest": "~0.9.0",
|
"supertest": "~0.9.0",
|
||||||
"chai": "~1.9.0",
|
"chai": "~1.9.0",
|
||||||
"loopback-testing": "~0.1.2"
|
"loopback-testing": "~0.1.2",
|
||||||
|
"browserify": "~3.30.2",
|
||||||
|
"grunt": "~0.4.2",
|
||||||
|
"grunt-browserify": "~1.3.1",
|
||||||
|
"grunt-contrib-uglify": "~0.3.2",
|
||||||
|
"grunt-contrib-jshint": "~0.8.0",
|
||||||
|
"grunt-contrib-watch": "~0.5.3",
|
||||||
|
"karma-script-launcher": "~0.1.0",
|
||||||
|
"karma-chrome-launcher": "~0.1.2",
|
||||||
|
"karma-firefox-launcher": "~0.1.3",
|
||||||
|
"karma-html2js-preprocessor": "~0.1.0",
|
||||||
|
"karma-phantomjs-launcher": "~0.1.2",
|
||||||
|
"karma": "~0.10.9",
|
||||||
|
"karma-browserify": "0.1.0",
|
||||||
|
"karma-mocha": "~0.1.1",
|
||||||
|
"grunt-karma": "~0.6.2"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/strongloop/loopback"
|
"url": "https://github.com/strongloop/loopback"
|
||||||
},
|
},
|
||||||
"license": "MIT"
|
"browser": {
|
||||||
|
"express": "./lib/browser-express.js",
|
||||||
|
"connect": false,
|
||||||
|
"passport": false,
|
||||||
|
"passport-local": false
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Dual MIT/StrongLoop",
|
||||||
|
"url": "https://github.com/strongloop/loopback/blob/master/LICENSE"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1139
test/README.md
1139
test/README.md
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,16 @@ describe('app', function() {
|
||||||
expect(app.remotes().exports).to.eql({ color: Color });
|
expect(app.remotes().exports).to.eql({ color: Color });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('updates REST API when a new model is added', function(done) {
|
||||||
|
app.use(loopback.rest());
|
||||||
|
request(app).get('/colors').expect(404, function(err, res) {
|
||||||
|
if (err) return done(err);
|
||||||
|
var Color = db.createModel('color', {name: String});
|
||||||
|
app.model(Color);
|
||||||
|
request(app).get('/colors').expect(200, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('in compat mode', function() {
|
describe('in compat mode', function() {
|
||||||
before(function() {
|
before(function() {
|
||||||
loopback.compat.usePluralNamesForRemoting = true;
|
loopback.compat.usePluralNamesForRemoting = true;
|
||||||
|
@ -38,7 +48,6 @@ describe('app', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses plural name as shared class name', function() {
|
it('uses plural name as shared class name', function() {
|
||||||
loopback.compat.usePluralNamesForRemoting = true;
|
|
||||||
var Color = db.createModel('color', {name: String});
|
var Color = db.createModel('color', {name: String});
|
||||||
app.model(Color);
|
app.model(Color);
|
||||||
expect(app.remotes().exports).to.eql({ colors: Color });
|
expect(app.remotes().exports).to.eql({ colors: Color });
|
||||||
|
@ -49,7 +58,6 @@ describe('app', function() {
|
||||||
app.model(Color);
|
app.model(Color);
|
||||||
expect(app.remoteObjects()).to.eql({ colors: Color });
|
expect(app.remoteObjects()).to.eql({ colors: Color });
|
||||||
});
|
});
|
||||||
;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -189,6 +197,12 @@ describe('app', function() {
|
||||||
var app = this.boot();
|
var app = this.boot();
|
||||||
assert.equal(app.get('host'), process.env.npm_config_host);
|
assert.equal(app.get('host'), process.env.npm_config_host);
|
||||||
|
|
||||||
|
delete process.env.npm_config_host;
|
||||||
|
delete process.env.OPENSHIFT_SLS_IP;
|
||||||
|
delete process.env.OPENSHIFT_NODEJS_IP;
|
||||||
|
delete process.env.HOST;
|
||||||
|
delete process.env.npm_package_config_host;
|
||||||
|
|
||||||
process.env.npm_config_port = randomPort();
|
process.env.npm_config_port = randomPort();
|
||||||
process.env.OPENSHIFT_SLS_PORT = randomPort();
|
process.env.OPENSHIFT_SLS_PORT = randomPort();
|
||||||
process.env.OPENSHIFT_NODEJS_PORT = randomPort();
|
process.env.OPENSHIFT_NODEJS_PORT = randomPort();
|
||||||
|
@ -198,6 +212,12 @@ describe('app', function() {
|
||||||
var app = this.boot();
|
var app = this.boot();
|
||||||
assert.equal(app.get('host'), process.env.npm_config_host);
|
assert.equal(app.get('host'), process.env.npm_config_host);
|
||||||
assert.equal(app.get('port'), process.env.npm_config_port);
|
assert.equal(app.get('port'), process.env.npm_config_port);
|
||||||
|
|
||||||
|
delete process.env.npm_config_port;
|
||||||
|
delete process.env.OPENSHIFT_SLS_PORT;
|
||||||
|
delete process.env.OPENSHIFT_NODEJS_PORT;
|
||||||
|
delete process.env.PORT;
|
||||||
|
delete process.env.npm_package_config_port;
|
||||||
});
|
});
|
||||||
|
|
||||||
function randomHost() {
|
function randomHost() {
|
||||||
|
@ -207,6 +227,18 @@ describe('app', function() {
|
||||||
function randomPort() {
|
function randomPort() {
|
||||||
return Math.floor(Math.random() * 10000);
|
return Math.floor(Math.random() * 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it('should honor 0 for free port', function () {
|
||||||
|
var app = loopback();
|
||||||
|
app.boot({app: {port: 0}});
|
||||||
|
assert.equal(app.get('port'), 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should default to port 3000', function () {
|
||||||
|
var app = loopback();
|
||||||
|
app.boot({app: {port: undefined}});
|
||||||
|
assert.equal(app.get('port'), 3000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Instantiate models', function () {
|
it('Instantiate models', function () {
|
||||||
|
@ -420,7 +452,8 @@ describe('app', function() {
|
||||||
|
|
||||||
assert.equal(typeof res.body, 'object');
|
assert.equal(typeof res.body, 'object');
|
||||||
assert(res.body.started);
|
assert(res.body.started);
|
||||||
assert(res.body.uptime);
|
// The number can be 0
|
||||||
|
assert(res.body.uptime !== undefined);
|
||||||
|
|
||||||
var elapsed = Date.now() - Number(new Date(res.body.started));
|
var elapsed = Date.now() - Number(new Date(res.body.started));
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
{
|
{
|
||||||
"port": 3000,
|
"port": 3000,
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"cookieSecret": "2d13a01d-44fb-455c-80cb-db9cb3cd3cd0"
|
"cookieSecret": "2d13a01d-44fb-455c-80cb-db9cb3cd3cd0",
|
||||||
|
"remoting": {
|
||||||
|
"json": {
|
||||||
|
"limit": "1kb",
|
||||||
|
"strict": false
|
||||||
|
},
|
||||||
|
"urlencoded": {
|
||||||
|
"limit": "8kb"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
|
require('./support');
|
||||||
var ACL = require('../').ACL;
|
var ACL = require('../').ACL;
|
||||||
|
var loopback = require('../');
|
||||||
|
|
||||||
describe('Model', function() {
|
describe('Model', function() {
|
||||||
|
|
||||||
|
@ -194,21 +196,21 @@ describe('Model', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Model.deleteById([callback])', function () {
|
describe('Model.deleteById([callback])', function () {
|
||||||
it("Delete a model instance from the attached data source", function (done) {
|
it("Delete a model instance from the attached data source", function (done) {
|
||||||
User.create({first: 'joe', last: 'bob'}, function (err, user) {
|
User.create({first: 'joe', last: 'bob'}, function (err, user) {
|
||||||
User.deleteById(user.id, function (err) {
|
User.deleteById(user.id, function (err) {
|
||||||
User.findById(user.id, function (err, notFound) {
|
User.findById(user.id, function (err, notFound) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(notFound, null);
|
assert.equal(notFound, null);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Model.destroyAll(callback)', function() {
|
describe('Model.destroyAll(callback)', function() {
|
||||||
it("Delete all Model instances from data source", function(done) {
|
it("Delete all Model instances from data source", function(done) {
|
||||||
(new TaskEmitter())
|
(new TaskEmitter())
|
||||||
.task(User, 'create', {first: 'jill'})
|
.task(User, 'create', {first: 'jill'})
|
||||||
|
@ -260,7 +262,8 @@ describe('Model', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Remote Methods', function(){
|
describe.onServer('Remote Methods', function(){
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
User.login = function (username, password, fn) {
|
User.login = function (username, password, fn) {
|
||||||
if(username === 'foo' && password === 'bar') {
|
if(username === 'foo' && password === 'bar') {
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
var loopback = require('../');
|
||||||
|
var lt = require('loopback-testing');
|
||||||
|
var path = require('path');
|
||||||
|
var SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app');
|
||||||
|
var app = require(path.join(SIMPLE_APP, 'app.js'));
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
describe('remoting - integration', function () {
|
||||||
|
|
||||||
|
lt.beforeEach.withApp(app);
|
||||||
|
lt.beforeEach.givenModel('store');
|
||||||
|
|
||||||
|
afterEach(function (done) {
|
||||||
|
this.app.models.store.destroyAll(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('app.remotes.options', function () {
|
||||||
|
it("should load remoting options", function () {
|
||||||
|
var remotes = app.remotes();
|
||||||
|
assert.deepEqual(remotes.options, {"json": {"limit": "1kb", "strict": false},
|
||||||
|
"urlencoded": {"limit": "8kb"}});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rest handler", function () {
|
||||||
|
var handler = app.handler('rest');
|
||||||
|
assert(handler);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept request that has entity below 1kb', function (done) {
|
||||||
|
// Build an object that is smaller than 1kb
|
||||||
|
var name = "";
|
||||||
|
for (var i = 0; i < 256; i++) {
|
||||||
|
name += "11";
|
||||||
|
}
|
||||||
|
this.http = this.post('/api/stores');
|
||||||
|
this.http.send({
|
||||||
|
"name": name
|
||||||
|
});
|
||||||
|
this.http.end(function (err) {
|
||||||
|
if (err) return done(err);
|
||||||
|
this.req = this.http.req;
|
||||||
|
this.res = this.http.res;
|
||||||
|
assert.equal(this.res.statusCode, 200);
|
||||||
|
done();
|
||||||
|
}.bind(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject request that has entity beyond 1kb', function (done) {
|
||||||
|
// Build an object that is larger than 1kb
|
||||||
|
var name = "";
|
||||||
|
for (var i = 0; i < 2048; i++) {
|
||||||
|
name += "11111111111";
|
||||||
|
}
|
||||||
|
this.http = this.post('/api/stores');
|
||||||
|
this.http.send({
|
||||||
|
"name": name
|
||||||
|
});
|
||||||
|
this.http.end(function (err) {
|
||||||
|
if (err) return done(err);
|
||||||
|
this.req = this.http.req;
|
||||||
|
this.res = this.http.res;
|
||||||
|
// Request is rejected with 413
|
||||||
|
assert.equal(this.res.statusCode, 413);
|
||||||
|
done();
|
||||||
|
}.bind(this));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
;
|
|
@ -16,6 +16,8 @@ describe('role model', function () {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
ds = loopback.createDataSource({connector: 'memory'});
|
ds = loopback.createDataSource({connector: 'memory'});
|
||||||
|
// Re-attach the models so that they can have isolated store to avoid
|
||||||
|
// pollutions from other tests
|
||||||
User.attachTo(ds);
|
User.attachTo(ds);
|
||||||
Role.attachTo(ds);
|
Role.attachTo(ds);
|
||||||
RoleMapping.attachTo(ds);
|
RoleMapping.attachTo(ds);
|
||||||
|
|
|
@ -11,7 +11,6 @@ app = null;
|
||||||
TaskEmitter = require('strong-task-emitter');
|
TaskEmitter = require('strong-task-emitter');
|
||||||
request = require('supertest');
|
request = require('supertest');
|
||||||
|
|
||||||
|
|
||||||
// Speed up the password hashing algorithm
|
// Speed up the password hashing algorithm
|
||||||
// for tests using the built-in User model
|
// for tests using the built-in User model
|
||||||
loopback.User.settings.saltWorkFactor = 4;
|
loopback.User.settings.saltWorkFactor = 4;
|
||||||
|
@ -50,3 +49,19 @@ assert.isFunc = function (obj, name) {
|
||||||
assert(obj, 'cannot assert function ' + name + ' on object that doesnt exist');
|
assert(obj, 'cannot assert function ' + name + ' on object that doesnt exist');
|
||||||
assert(typeof obj[name] === 'function', name + ' is not a function');
|
assert(typeof obj[name] === 'function', name + ' is not a function');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe.onServer = function describeOnServer(name, fn) {
|
||||||
|
if (loopback.isServer) {
|
||||||
|
describe(name, fn);
|
||||||
|
} else {
|
||||||
|
describe.skip(name, fn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
describe.inBrowser = function describeInBrowser(name, fn) {
|
||||||
|
if (loopback.isBrowser) {
|
||||||
|
describe(name, fn);
|
||||||
|
} else {
|
||||||
|
describe.skip(name, fn);
|
||||||
|
}
|
||||||
|
};
|
|
@ -4,7 +4,7 @@ var passport = require('passport');
|
||||||
var MailConnector = require('../lib/connectors/mail');
|
var MailConnector = require('../lib/connectors/mail');
|
||||||
|
|
||||||
var userMemory = loopback.createDataSource({
|
var userMemory = loopback.createDataSource({
|
||||||
connector: loopback.Memory
|
connector: 'memory'
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('User', function(){
|
describe('User', function(){
|
||||||
|
@ -14,11 +14,12 @@ describe('User', function(){
|
||||||
User.email = loopback.Email.extend('email');
|
User.email = loopback.Email.extend('email');
|
||||||
loopback.autoAttach();
|
loopback.autoAttach();
|
||||||
|
|
||||||
|
// Update the AccessToken relation to use the subclass of User
|
||||||
|
AccessToken.belongsTo(User);
|
||||||
|
|
||||||
// allow many User.afterRemote's to be called
|
// allow many User.afterRemote's to be called
|
||||||
User.setMaxListeners(0);
|
User.setMaxListeners(0);
|
||||||
|
|
||||||
User.hasMany(AccessToken, {as: 'accessTokens', foreignKey: 'userId'});
|
|
||||||
AccessToken.belongsTo(User);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
|
|
Loading…
Reference in New Issue