Compare commits

...

28 Commits

Author SHA1 Message Date
Diana Lau c8241b2b35
Merge pull request #308 from achrinzafork/chore/update-lts
chore: update LTS status to End-of-Life
2021-02-09 10:48:13 -05:00
Rifa Achrinza afe57b5b04 chore: update LTS status to End-of-Life
see https://github.com/strongloop/loopback-next/issues/6957
2021-01-22 11:13:00 +08:00
Miroslav Bajtoš 56dcfaab6c
Merge pull request #305 from strongloop/feat/maintenance-lts
Update LTS status in README
2020-03-05 17:28:05 +01:00
Miroslav Bajtoš 51ec554632
Update LTS status in README 2020-03-05 13:41:27 +01:00
Agnes Lin f4313949c3
Merge pull request #302 from strongloop/copyright
chore: update copyrights year
2020-02-10 08:32:31 -05:00
Diana Lau 98883a877f chore: update copyrights year 2020-02-08 17:01:01 -05:00
Diana Lau 7a6021dc77
Merge pull request #301 from strongloop/fixbot
fix stale bot
2020-02-06 08:58:27 -05:00
Diana Lau f9d6d147bc fix stale bot 2020-02-03 14:18:55 -05:00
Nora 298aec304a
Merge pull request #300 from strongloop/chore/improve-issue-templates
chore: improve issue and PR templates
2019-11-21 10:31:47 -05:00
Nora 0043b9e27d
Merge pull request #299 from strongloop/fix-eslint
chore: fix eslint violations
2019-11-21 10:31:38 -05:00
Nora 3cbe0028a4 chore: improve issue and PR templates 2019-11-17 14:22:06 -05:00
Nora e9b108f9c6 chore: fix eslint violations 2019-11-17 14:19:25 -05:00
Miroslav Bajtoš 0bbe8335a4
Merge pull request #297 from strongloop/fix/ci
test: fix browserify-based tests
2019-10-07 10:38:13 +02:00
Miroslav Bajtoš c11ba18f73
test: fix browserify-based tests
Add `packageFilter` to handle buggy `async` browserify config.

Signed-off-by: Miroslav Bajtoš <mbajtoss@gmail.com>
2019-10-03 17:06:12 +02:00
Miroslav Bajtoš 1fec4ea375
Merge pull request #298 from strongloop/drop-node6
Drop support for Node.js 6.x
2019-10-03 17:03:36 +02:00
Miroslav Bajtoš 974c63ccd5
Drop support for Node.js 6.x
It has reached end-of-life long time.

Signed-off-by: Miroslav Bajtoš <mbajtoss@gmail.com>
2019-10-03 16:57:02 +02:00
Diana Lau f6b2f24b29
Merge pull request #296 from strongloop/stalebot
chore: add stalebot
2019-09-19 10:00:00 -04:00
Diana Lau b4d1f96494 chore: add stalebot 2019-09-19 09:36:49 -04:00
Diana Lau 6d8d9c92ce
Merge pull request #293 from strongloop/fix/publish-config
Tag 3.x versions as `latest` in npm registry
2019-06-25 09:54:04 -04:00
Miroslav Bajtoš 14050c199f
Tag 3.x versions as `latest` in npm registry
Signed-off-by: Miroslav Bajtoš <mbajtoss@gmail.com>
2019-06-25 08:38:07 +02:00
Diana Lau 59e46b3d91 3.3.1
* chore: update LTS status (Diana Lau)
 * chore: update copyrights years (Agnes Lin)
2019-06-24 11:22:44 -04:00
Diana Lau 8bb4368ca8
Merge pull request #292 from strongloop/lts
chore: update LTS status
2019-06-18 15:33:11 -04:00
Diana Lau a1d2954626 chore: update LTS status 2019-06-12 21:54:11 -04:00
Agnes Lin 837b8185f2
Merge pull request #290 from strongloop/copyrights
chore: update copyrights years
2019-05-07 10:29:23 -04:00
Agnes Lin ef39abf6eb chore: update copyrights years 2019-05-07 10:16:03 -04:00
Raymond Feng 8587dd6a19 3.3.0
* chore: upgrade deps to avoid npm audit warnings (Raymond Feng)
2019-03-28 14:28:27 -07:00
Raymond Feng 561cbd5bca
Merge pull request #289 from strongloop/upgrade-deps
chore: upgrade deps to avoid npm audit warnings
2019-03-28 14:27:11 -07:00
Raymond Feng 02da15cd3e chore: upgrade deps to avoid npm audit warnings 2019-03-26 11:14:56 -07:00
61 changed files with 1216 additions and 1063 deletions

View File

@ -1,37 +0,0 @@
<!--
Questions:
https://groups.google.com/forum/#!forum/loopbackjs
https://gitter.im/strongloop/loopback
Immediate support:
https://strongloop.com/api-connect-faqs/
https://strongloop.com/node-js/subscription-plans/
-->
# Description/Steps to reproduce
<!--
If feature: A description of the feature
If bug: Steps to reproduce
-->
# Link to reproduction sandbox
<!--
Link to an app sandbox for reproduction
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
-->
# Expected result
<!--
Also include actual results if bug
-->
# Additional information
<!--
Copy+paste the output of these two commands:
node -e 'console.log(process.platform, process.arch, process.versions.node)'
npm ls --prod --depth 0 | grep loopback
-->

50
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@ -0,0 +1,50 @@
---
name: Bug report
about: Create a report to help us improve
labels: bug
---
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
HELP US HELP YOU, PLEASE
- Do a quick search to avoid duplicate issues
- Provide as much information as possible (reproduction sandbox, use case for features, etc.)
- Consider using a more suitable venue for questions such as Stack Overflow, Gitter, etc.
Please fill in the *entire* template below.
-->
## Steps to reproduce
<!-- Describe how to reproduce the issue -->
## Current Behavior
<!-- Describe the observed result -->
## Expected Behavior
<!-- Describe what did you expect instead, what is the desired outcome? -->
## Link to reproduction sandbox
<!--
See https://loopback.io/doc/en/contrib/Reporting-issues.html#loopback-3x-bugs
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
-->
## Additional information
<!--
Copy+paste the output of these two commands:
node -e 'console.log(process.platform, process.arch, process.versions.node)'
npm ls --prod --depth 0 | grep loopback
-->
## Related Issues
<!-- Did you find other bugs that looked similar? -->
_See [Reporting Issues](http://loopback.io/doc/en/contrib/Reporting-issues.html) for more tips on writing good issues_

View File

@ -0,0 +1,25 @@
---
name: Feature request
about: Suggest an idea for this project
labels: feature
---
## Suggestion
<!-- A summary of what you'd like to see added or changed -->
## Use Cases
<!--
What do you want to use this for?
What shortcomings exist with current approaches?
-->
## Examples
<!-- Show how this would be used and what the behavior would be -->
## Acceptance criteria
TBD - will be filled by the team.

27
.github/ISSUE_TEMPLATE/Question.md vendored Normal file
View File

@ -0,0 +1,27 @@
---
name: Question
about: The issue tracker is not for questions. Please use Stack Overflow or other resources for help.
labels: question
---
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
THE ISSUE TRACKER IS NOT FOR QUESTIONS.
DO NOT CREATE A NEW ISSUE TO ASK A QUESTION.
Please use one of the following resources for help:
**Questions**
- https://stackoverflow.com/tags/loopbackjs
- https://groups.google.com/forum/#!forum/loopbackjs
- https://gitter.im/strongloop/loopback
**Immediate support**
- https://strongloop.com/api-connect-faqs/
- https://strongloop.com/node-js/subscription-plans/
-->

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Report a security vulnerability
url: https://loopback.io/doc/en/contrib/Reporting-issues.html#security-issues
about: Do not report security vulnerabilities using GitHub issues. Please send an email to `reachsl@us.ibm.com` instead.
- name: Get help on StackOverflow
url: https://stackoverflow.com/tags/loopbackjs
about: Please ask and answer questions on StackOverflow.
- name: Join our mailing list
url: https://groups.google.com/forum/#!forum/loopbackjs
about: You can also post your question to our mailing list.

View File

@ -1,25 +1,18 @@
### Description
#### Related issues
<!-- <!--
Please use the following link syntaxes: Please provide a high-level description of the changes made by your pull request.
- connect to #49 (to reference issues in the current repository) Include references to all related GitHub issues and other pull requests, for example:
- connect to strongloop/loopback#49 (to reference issues in another repository)
Fixes #123
Implements #254
See also #23
--> -->
- connect to <link_to_referenced_issue> ## Checklist
### Checklist 👉 [Read and sign the CLA (Contributor License Agreement)](https://cla.strongloop.com/agreements/strongloop/loopback-boot) 👈
<!--
- Please mark your choice with an "x" (i.e. [x], see
https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments)
- PR's without test coverage will be closed.
-->
- [ ] `npm test` passes on your machine
- [ ] New tests added or existing tests modified to cover all changes - [ ] New tests added or existing tests modified to cover all changes
- [ ] Code conforms with the [style - [ ] Code conforms with the [style guide](https://loopback.io/doc/en/contrib/style-guide-es6.html)
guide](http://loopback.io/doc/en/contrib/style-guide.html) - [ ] Commit messages are following our [guidelines](https://loopback.io/doc/en/contrib/git-commit-messages.html)

24
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,24 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 14
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- critical
- p1
- major
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
This issue has been closed due to continued inactivity. Thank you for your understanding.
If you believe this to be in error, please contact one of the code owners,
listed in the `CODEOWNERS` file at the top-level of this repository.

View File

@ -1,7 +1,6 @@
sudo: false sudo: false
language: node_js language: node_js
node_js: node_js:
- "6"
- "8" - "8"
- "10" - "10"

View File

@ -1,3 +1,17 @@
2019-06-24, Version 3.3.1
=========================
* chore: update LTS status (Diana Lau)
* chore: update copyrights years (Agnes Lin)
2019-03-28, Version 3.3.0
=========================
* chore: upgrade deps to avoid npm audit warnings (Raymond Feng)
2019-03-22, Version 3.2.1 2019-03-22, Version 3.2.1
========================= =========================

View File

@ -1,12 +1,13 @@
# LoopBack Boot # LoopBack Boot
**This module is in Active LTS mode, new features are no longer accepted.** **⚠️ LoopBack 3 has reached end of life. We are no longer accepting pull requests or providing
<br/>(See [Module Long Term Support Policy](#module-long-term-support-policy) support for community users. The only exception is fixes for critical bugs and security
below.) vulnerabilities provided as part of support for IBM API Connect customers. (See
[Module Long Term Support Policy](#module-long-term-support-policy) below.)**
LoopBack 3 users looking for new features are encouraged to upgrade We urge all LoopBack 3 users to migrate their applications to LoopBack 4 as
to LoopBack 4. Refer to soon as possible. Refer to our
[loopback-next#1849](https://github.com/strongloop/loopback-next/issues/1849) [Migration Guide](https://loopback.io/doc/en/lb4/migration-overview.html)
for more information on how to upgrade. for more information on how to upgrade.
## Overview ## Overview
@ -63,8 +64,8 @@ with the following End Of Life (EOL) dates:
| Version | Status | Published | EOL | | Version | Status | Published | EOL |
| ------- | --------------- | --------- | -------- | | ------- | --------------- | --------- | -------- |
| 3.x | Active LTS | May 2017 | Dec 2019 | | 3.x | End-of-Life | May 2017 | Dec 2020 |
| 2.x | Maintenance LTS | Jul 2014 | Apr 2019 | | 2.x | End-of-Life | Jul 2014 | Apr 2019 |
Learn more about our LTS plan in [docs](https://loopback.io/doc/en/contrib/Long-term-support.html). Learn more about our LTS plan in [docs](https://loopback.io/doc/en/contrib/Long-term-support.html).

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var Bootstrapper = require('./lib/bootstrapper'); const Bootstrapper = require('./lib/bootstrapper');
/** /**
* The browser version of `bootLoopBackApp`. * The browser version of `bootLoopBackApp`.
@ -26,18 +26,18 @@ var Bootstrapper = require('./lib/bootstrapper');
exports = module.exports = function bootBrowserApp(app, options, callback) { exports = module.exports = function bootBrowserApp(app, options, callback) {
// Only using options.id to identify the browserified bundle to load for // Only using options.id to identify the browserified bundle to load for
// this application. If no Id was provided, load the default bundle. // this application. If no Id was provided, load the default bundle.
var moduleName = 'loopback-boot#instructions'; let moduleName = 'loopback-boot#instructions';
var appId = options && typeof options === 'object' && options.appId; const appId = options && typeof options === 'object' && options.appId;
if (appId) if (appId)
moduleName += '-' + appId; moduleName += '-' + appId;
// The name of the module containing instructions // The name of the module containing instructions
// is hard-coded in lib/bundler // is hard-coded in lib/bundler
var instructions = require(moduleName); const instructions = require(moduleName);
var bootstrapper = new Bootstrapper(options); const bootstrapper = new Bootstrapper(options);
bootstrapper.phases = ['starting', 'start', 'started']; bootstrapper.phases = ['starting', 'start', 'started'];
var context = { const context = {
app: app, app: app,
instructions: instructions, instructions: instructions,
}; };

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
@ -6,11 +6,11 @@
'use strict'; 'use strict';
// Strong globalize // Strong globalize
var g = require('./lib/globalize'); const g = require('./lib/globalize');
var PluginBase = require('./lib/plugin-base'); const PluginBase = require('./lib/plugin-base');
var Bootstrapper = require('./lib/bootstrapper'); const Bootstrapper = require('./lib/bootstrapper');
var addInstructionsToBrowserify = require('./lib/bundler'); const addInstructionsToBrowserify = require('./lib/bundler');
/** /**
* Initialize an application from an options object or * Initialize an application from an options object or
@ -158,9 +158,9 @@ exports = module.exports = function bootLoopBackApp(app, options, callback) {
// backwards compatibility with loopback's app.boot // backwards compatibility with loopback's app.boot
options.env = options.env || app.get('env'); options.env = options.env || app.get('env');
var bootstrapper = new Bootstrapper(options); const bootstrapper = new Bootstrapper(options);
var context = { const context = {
bootstrapper: bootstrapper, bootstrapper: bootstrapper,
app: app, app: app,
}; };
@ -169,9 +169,9 @@ exports = module.exports = function bootLoopBackApp(app, options, callback) {
}; };
exports.compile = function(options, done) { exports.compile = function(options, done) {
var bootstrapper = new Bootstrapper(options); const bootstrapper = new Bootstrapper(options);
bootstrapper.phases = ['load', 'compile']; bootstrapper.phases = ['load', 'compile'];
var context = {}; const context = {};
return bootstrapper.run(context, done); return bootstrapper.run(context, done);
}; };
@ -199,10 +199,10 @@ exports.Bootstrapper = Bootstrapper;
exports.PluginBase = PluginBase; exports.PluginBase = PluginBase;
exports.execute = function(app, instructions, done) { exports.execute = function(app, instructions, done) {
var bootstrapper = new Bootstrapper( const bootstrapper = new Bootstrapper(
{phases: ['starting', 'start', 'started']} {phases: ['starting', 'start', 'started']},
); );
var context = { const context = {
app: app, app: app,
instructions: instructions, instructions: instructions,
}; };

64
lib/bootstrapper.js vendored
View File

@ -1,25 +1,25 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var _ = require('lodash'); const _ = require('lodash');
var assert = require('assert'); const assert = require('assert');
var async = require('async'); const async = require('async');
var utils = require('./utils'); const utils = require('./utils');
var path = require('path'); const path = require('path');
var pluginLoader = require('./plugin-loader'); const pluginLoader = require('./plugin-loader');
var debug = require('debug')('loopback:boot:bootstrapper'); const debug = require('debug')('loopback:boot:bootstrapper');
var Promise = require('bluebird'); const Promise = require('bluebird');
var arrayToObject = require('./utils').arrayToObject; const arrayToObject = require('./utils').arrayToObject;
module.exports = Bootstrapper; module.exports = Bootstrapper;
function createPromiseCallback() { function createPromiseCallback() {
var cb; let cb;
var promise = new Promise(function(resolve, reject) { const promise = new Promise(function(resolve, reject) {
cb = function(err, data) { cb = function(err, data) {
if (err) return reject(err); if (err) return reject(err);
return resolve(data); return resolve(data);
@ -29,22 +29,22 @@ function createPromiseCallback() {
return cb; return cb;
} }
var builtinPlugins = [ const builtinPlugins = [
'application', 'datasource', 'model', 'mixin', 'application', 'datasource', 'model', 'mixin',
'middleware', 'component', 'boot-script', 'swagger', 'middleware', 'component', 'boot-script', 'swagger',
]; ];
var builtinPhases = [ const builtinPhases = [
'load', 'compile', 'starting', 'start', 'started', 'load', 'compile', 'starting', 'start', 'started',
]; ];
function loadAndRegisterPlugins(bootstrapper, options) { function loadAndRegisterPlugins(bootstrapper, options) {
var loader = pluginLoader(options); const loader = pluginLoader(options);
var loaderContext = {}; const loaderContext = {};
loader.load(loaderContext); loader.load(loaderContext);
loader.compile(loaderContext); loader.compile(loaderContext);
for (var i in loaderContext.instructions.pluginScripts) { for (const i in loaderContext.instructions.pluginScripts) {
bootstrapper.use('/boot/' + i, loaderContext.instructions.pluginScripts[i]); bootstrapper.use('/boot/' + i, loaderContext.instructions.pluginScripts[i]);
} }
} }
@ -65,13 +65,13 @@ function Bootstrapper(options) {
// For setting properties without modifying the original object // For setting properties without modifying the original object
options = Object.create(options); options = Object.create(options);
var appRootDir = options.appRootDir = options.appRootDir || process.cwd(); const appRootDir = options.appRootDir = options.appRootDir || process.cwd();
var env = options.env || process.env.NODE_ENV || 'development'; const env = options.env || process.env.NODE_ENV || 'development';
var scriptExtensions = options.scriptExtensions ? const scriptExtensions = options.scriptExtensions ?
arrayToObject(options.scriptExtensions) : arrayToObject(options.scriptExtensions) :
require.extensions; require.extensions;
var appConfigRootDir = options.appConfigRootDir || appRootDir; const appConfigRootDir = options.appConfigRootDir || appRootDir;
options.rootDir = appConfigRootDir; options.rootDir = appConfigRootDir;
options.env = env; options.env = env;
@ -84,9 +84,9 @@ function Bootstrapper(options) {
assert(Array.isArray(this.plugins), 'Invalid plugins: ' + assert(Array.isArray(this.plugins), 'Invalid plugins: ' +
this.builtinPlugins); this.builtinPlugins);
var self = this; const self = this;
self.builtinPlugins.forEach(function(p) { self.builtinPlugins.forEach(function(p) {
var factory = require('./plugins/' + p); const factory = require('./plugins/' + p);
self.use('/boot/' + p, factory(options)); self.use('/boot/' + p, factory(options));
}); });
@ -103,7 +103,7 @@ function Bootstrapper(options) {
* @param {Function} handler * @param {Function} handler
*/ */
Bootstrapper.prototype.use = function(path, handler) { Bootstrapper.prototype.use = function(path, handler) {
var plugin = { const plugin = {
path: path, path: path,
handler: handler, handler: handler,
}; };
@ -135,7 +135,7 @@ Bootstrapper.prototype.getExtensions = function(path) {
} }
return this.plugins.filter(function(p) { return this.plugins.filter(function(p) {
if (p.path.indexOf(path) === -1) return false; if (p.path.indexOf(path) === -1) return false;
var name = p.path.substring(path.length); const name = p.path.substring(path.length);
return name && name.indexOf('/') === -1; return name && name.indexOf('/') === -1;
}); });
}; };
@ -153,7 +153,7 @@ Bootstrapper.prototype.addPhases = function(phases) {
function pluginIteratorFactory(context, phase) { function pluginIteratorFactory(context, phase) {
return function executePluginPhase(plugin, done) { return function executePluginPhase(plugin, done) {
var result; let result;
if (typeof plugin.handler[phase] !== 'function') { if (typeof plugin.handler[phase] !== 'function') {
debug('Skipping %s.%s', plugin.handler.name, phase); debug('Skipping %s.%s', plugin.handler.name, phase);
return done(); return done();
@ -190,24 +190,24 @@ Bootstrapper.prototype.run = function(context, done) {
if (!done) { if (!done) {
done = createPromiseCallback(); done = createPromiseCallback();
} }
var options = this.options; const options = this.options;
var appRootDir = options.appRootDir = options.appRootDir || process.cwd(); const appRootDir = options.appRootDir = options.appRootDir || process.cwd();
var env = options.env || process.env.NODE_ENV || 'development'; const env = options.env || process.env.NODE_ENV || 'development';
var appConfigRootDir = options.appConfigRootDir || appRootDir; const appConfigRootDir = options.appConfigRootDir || appRootDir;
options.rootDir = appConfigRootDir; options.rootDir = appConfigRootDir;
options.env = env; options.env = env;
context = context || {}; context = context || {};
var phases = context.phases || this.phases; const phases = context.phases || this.phases;
if (phases.includes('starting') || phases.includes('start')) { if (phases.includes('starting') || phases.includes('start')) {
context.app.booting = true; context.app.booting = true;
} }
var bootPlugins = this.getExtensions('/boot'); const bootPlugins = this.getExtensions('/boot');
async.eachSeries(phases, function(phase, done) { async.eachSeries(phases, function(phase, done) {
debug('Phase %s', phase); debug('Phase %s', phase);
async.eachSeries(bootPlugins, pluginIteratorFactory(context, phase), done); async.eachSeries(bootPlugins, pluginIteratorFactory(context, phase), done);

View File

@ -1,15 +1,15 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var fs = require('fs'); const fs = require('fs');
var path = require('path'); const path = require('path');
var commondir = require('commondir'); const commondir = require('commondir');
var cloneDeep = require('lodash').cloneDeep; const cloneDeep = require('lodash').cloneDeep;
var g = require('./globalize'); const g = require('./globalize');
/** /**
* Add boot instructions to a browserify bundler. * Add boot instructions to a browserify bundler.
@ -27,8 +27,8 @@ module.exports = function addInstructionsToBrowserify(context, bundler) {
}; };
function addPlugins(bundler) { function addPlugins(bundler) {
var dir = path.join(__dirname, './plugins'); const dir = path.join(__dirname, './plugins');
var files = fs.readdirSync(dir); const files = fs.readdirSync(dir);
files.forEach(function(f) { files.forEach(function(f) {
bundler.require(path.join(dir, f), bundler.require(path.join(dir, f),
{expose: './plugins/' + path.basename(f, '.js')}); {expose: './plugins/' + path.basename(f, '.js')});
@ -36,12 +36,12 @@ function addPlugins(bundler) {
} }
function bundleOtherScripts(context, bundler) { function bundleOtherScripts(context, bundler) {
var list = context.instructions.bootScripts; const list = context.instructions.bootScripts;
addScriptsToBundle('boot', list, bundler); addScriptsToBundle('boot', list, bundler);
} }
function bundlePluginScripts(context, bundler) { function bundlePluginScripts(context, bundler) {
var list = context.instructions.pluginScripts; const list = context.instructions.pluginScripts;
addScriptsToBundle('plugins', list, bundler); addScriptsToBundle('plugins', list, bundler);
} }
@ -58,11 +58,11 @@ function bundleComponentScripts(context, bundler) {
} }
function bundleSourceFiles(context, type, bundler) { function bundleSourceFiles(context, type, bundler) {
var files = context.instructions[type] const files = context.instructions[type]
.map(function(m) { return m.sourceFile; }) .map(function(m) { return m.sourceFile; })
.filter(function(f) { return !!f; }); .filter(function(f) { return !!f; });
var instructionToFileMapping = context.instructions[type] const instructionToFileMapping = context.instructions[type]
.map(function(m) { return files.indexOf(m.sourceFile); }); .map(function(m) { return files.indexOf(m.sourceFile); });
addScriptsToBundle(type, files, bundler); addScriptsToBundle(type, files, bundler);
@ -77,15 +77,16 @@ function bundleSourceFiles(context, type, bundler) {
function addScriptsToBundle(name, list, bundler) { function addScriptsToBundle(name, list, bundler) {
if (!list.length) return; if (!list.length) return;
var root = commondir(list.map(path.dirname)); const root = commondir(list.map(path.dirname));
for (var ix in list) { for (const ix in list) {
var filepath = list[ix]; const filepath = list[ix];
// Build a short unique id that does not expose too much // Build a short unique id that does not expose too much
// information about the file system, but still preserves // information about the file system, but still preserves
// useful information about where is the file coming from. // useful information about where is the file coming from.
var fileid = 'loopback-boot#' + name + '#' + path.relative(root, filepath); const fileid =
'loopback-boot#' + name + '#' + path.relative(root, filepath);
// Add the file to the bundle. // Add the file to the bundle.
bundler.require(filepath, {expose: fileid}); bundler.require(filepath, {expose: fileid});
@ -97,19 +98,19 @@ function addScriptsToBundle(name, list, bundler) {
} }
function bundleInstructions(context, bundler) { function bundleInstructions(context, bundler) {
var instructions = cloneDeep(context.instructions); const instructions = cloneDeep(context.instructions);
var hasMiddleware = instructions.middleware.phases.length || const hasMiddleware = instructions.middleware.phases.length ||
instructions.middleware.middleware.length; instructions.middleware.middleware.length;
if (hasMiddleware) { if (hasMiddleware) {
g.warn( g.warn(
'Discarding {{middleware}} instructions,' + 'Discarding {{middleware}} instructions,' +
' {{loopback}} client does not support {{middleware}}.' ' {{loopback}} client does not support {{middleware}}.',
); );
} }
delete instructions.middleware; delete instructions.middleware;
var instructionsString = JSON.stringify(instructions, null, 2); const instructionsString = JSON.stringify(instructions, null, 2);
/* The following code does not work due to a bug in browserify /* The following code does not work due to a bug in browserify
* https://github.com/substack/node-browserify/issues/771 * https://github.com/substack/node-browserify/issues/771
@ -119,7 +120,7 @@ function bundleInstructions(context, bundler) {
b.require(instructionsStream, { expose: 'loopback-boot#instructions' }); b.require(instructionsStream, { expose: 'loopback-boot#instructions' });
*/ */
var instructionId = 'instructions'; let instructionId = 'instructions';
// Create an unique instruction identifier using the application ID. // Create an unique instruction identifier using the application ID.
// This is only useful when multiple loopback applications are being bundled // This is only useful when multiple loopback applications are being bundled
// together. // together.
@ -128,10 +129,10 @@ function bundleInstructions(context, bundler) {
// Write the instructions to a file in our node_modules folder. // Write the instructions to a file in our node_modules folder.
// The location should not really matter as long as it is .gitignore-ed // The location should not really matter as long as it is .gitignore-ed
var instructionsFile = path.resolve(__dirname, const instructionsFile = path.resolve(__dirname,
'..', 'generated-' + instructionId + '.json'); '..', 'generated-' + instructionId + '.json');
fs.writeFileSync(instructionsFile, instructionsString, 'utf-8'); fs.writeFileSync(instructionsFile, instructionsString, 'utf-8');
var moduleName = 'loopback-boot#' + instructionId; const moduleName = 'loopback-boot#' + instructionId;
bundler.require(instructionsFile, {expose: moduleName}); bundler.require(instructionsFile, {expose: moduleName});
} }

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var path = require('path'); const path = require('path');
var SG = require('strong-globalize'); const SG = require('strong-globalize');
SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'}); SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'});
module.exports = SG(); module.exports = SG();

View File

@ -1,17 +1,17 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var fs = require('fs'); const fs = require('fs');
var path = require('path'); const path = require('path');
var debug = require('debug')('loopback:boot:plugin'); const debug = require('debug')('loopback:boot:plugin');
var assert = require('assert'); const assert = require('assert');
var _ = require('lodash'); const _ = require('lodash');
var util = require('./utils'); const util = require('./utils');
var g = require('./globalize'); const g = require('./globalize');
module.exports = PluginBase; module.exports = PluginBase;
@ -26,11 +26,11 @@ PluginBase.prototype.getRootDir = function() {
}; };
PluginBase.prototype.load = function(context) { PluginBase.prototype.load = function(context) {
var rootDir = this.getRootDir() || this.options.rootDir; const rootDir = this.getRootDir() || this.options.rootDir;
var env = this.options.env; const env = this.options.env;
assert(this.name, 'Plugin name must to be set'); assert(this.name, 'Plugin name must to be set');
debug('Root dir: %s, env: %s, artifact: %s', rootDir, env, this.artifact); debug('Root dir: %s, env: %s, artifact: %s', rootDir, env, this.artifact);
var config = {}; let config = {};
if (this.options[this.name]) { if (this.options[this.name]) {
// First check if options have the corresponding config object // First check if options have the corresponding config object
debug('Artifact: %s is using provided config obj instead' + debug('Artifact: %s is using provided config obj instead' +
@ -67,7 +67,7 @@ PluginBase.prototype.merge = function(target, config, keyPrefix) {
* @returns {Object} * @returns {Object}
*/ */
PluginBase.prototype.loadNamed = function(rootDir, env, name) { PluginBase.prototype.loadNamed = function(rootDir, env, name) {
var files = this.findConfigFiles(rootDir, env, name); const files = this.findConfigFiles(rootDir, env, name);
debug('Looking in dir %s for %s configs', rootDir, this.name); debug('Looking in dir %s for %s configs', rootDir, this.name);
if (files.length) { if (files.length) {
debug('found %s %s files: %j', env, name, files); debug('found %s %s files: %j', env, name, files);
@ -75,8 +75,8 @@ PluginBase.prototype.loadNamed = function(rootDir, env, name) {
debug(' %s', f); debug(' %s', f);
}); });
} }
var configs = this._loadConfigFiles(files); const configs = this._loadConfigFiles(files);
var merged = this._mergeConfigurations(configs); const merged = this._mergeConfigurations(configs);
debug('merged %s %s configuration %j', env, name, merged); debug('merged %s %s configuration %j', env, name, merged);
@ -92,14 +92,14 @@ PluginBase.prototype.loadNamed = function(rootDir, env, name) {
* @returns {Array.<String>} Array of absolute file paths. * @returns {Array.<String>} Array of absolute file paths.
*/ */
PluginBase.prototype.findConfigFiles = function(rootDir, env, name, exts) { PluginBase.prototype.findConfigFiles = function(rootDir, env, name, exts) {
var master = ifExists(name + '.json'); const master = ifExists(name + '.json');
if (!master && (ifExistsWithAnyExt(name + '.local') || if (!master && (ifExistsWithAnyExt(name + '.local') ||
ifExistsWithAnyExt(name + '.' + env))) { ifExistsWithAnyExt(name + '.' + env))) {
g.warn('WARNING: Main config file "%s{{.json}}" is missing', name); g.warn('WARNING: Main config file "%s{{.json}}" is missing', name);
} }
if (!master) return []; if (!master) return [];
var candidates = [ const candidates = [
master, master,
ifExistsWithAnyExt(name + '.local'), ifExistsWithAnyExt(name + '.local'),
ifExistsWithAnyExt(name + '.' + env), ifExistsWithAnyExt(name + '.' + env),
@ -110,14 +110,14 @@ PluginBase.prototype.findConfigFiles = function(rootDir, env, name, exts) {
}); });
function ifExists(fileName) { function ifExists(fileName) {
var filePath = path.resolve(rootDir, fileName); const filePath = path.resolve(rootDir, fileName);
return util.fileExistsSync(filePath) ? filePath : undefined; return util.fileExistsSync(filePath) ? filePath : undefined;
} }
function ifExistsWithAnyExt(fileName) { function ifExistsWithAnyExt(fileName) {
var extensions = exts || ['js', 'json']; const extensions = exts || ['js', 'json'];
var file; let file;
for (var i = 0, n = extensions.length; i < n; i++) { for (let i = 0, n = extensions.length; i < n; i++) {
file = ifExists(fileName + '.' + extensions[i]); file = ifExists(fileName + '.' + extensions[i]);
if (file) { if (file) {
return file; return file;
@ -134,7 +134,7 @@ PluginBase.prototype.findConfigFiles = function(rootDir, env, name, exts) {
*/ */
PluginBase.prototype._loadConfigFiles = function(files) { PluginBase.prototype._loadConfigFiles = function(files) {
return files.map(function(f) { return files.map(function(f) {
var config = require(f); let config = require(f);
config = _.cloneDeep(config); config = _.cloneDeep(config);
Object.defineProperty(config, '_filename', { Object.defineProperty(config, '_filename', {
enumerable: false, enumerable: false,
@ -149,18 +149,18 @@ PluginBase.prototype._loadConfigFiles = function(files) {
* @param {Array.<Object>} configObjects * @param {Array.<Object>} configObjects
*/ */
PluginBase.prototype._mergeConfigurations = function(configObjects) { PluginBase.prototype._mergeConfigurations = function(configObjects) {
var result = configObjects.shift() || {}; const result = configObjects.shift() || {};
while (configObjects.length) { while (configObjects.length) {
var next = configObjects.shift(); const next = configObjects.shift();
this.merge(result, next, next._filename); this.merge(result, next, next._filename);
} }
return result; return result;
}; };
PluginBase.prototype._mergeObjects = function(target, config, keyPrefix) { PluginBase.prototype._mergeObjects = function(target, config, keyPrefix) {
for (var key in config) { for (const key in config) {
var fullKey = keyPrefix ? keyPrefix + '.' + key : key; const fullKey = keyPrefix ? keyPrefix + '.' + key : key;
var err = this._mergeSingleItemOrProperty(target, config, key, fullKey); const err = this._mergeSingleItemOrProperty(target, config, key, fullKey);
if (err) throw err; if (err) throw err;
} }
return null; // no error return null; // no error
@ -170,12 +170,12 @@ PluginBase.prototype._mergeNamedItems = function(arr1, arr2, key) {
assert(Array.isArray(arr1), 'invalid array: ' + arr1); assert(Array.isArray(arr1), 'invalid array: ' + arr1);
assert(Array.isArray(arr2), 'invalid array: ' + arr2); assert(Array.isArray(arr2), 'invalid array: ' + arr2);
key = key || 'name'; key = key || 'name';
var result = [].concat(arr1); const result = [].concat(arr1);
for (var i = 0, n = arr2.length; i < n; i++) { for (let i = 0, n = arr2.length; i < n; i++) {
var item = arr2[i]; const item = arr2[i];
var found = false; let found = false;
if (item[key]) { if (item[key]) {
for (var j = 0, k = result.length; j < k; j++) { for (let j = 0, k = result.length; j < k; j++) {
if (result[j][key] === item[key]) { if (result[j][key] === item[key]) {
this._mergeObjects(result[j], item); this._mergeObjects(result[j], item);
found = true; found = true;
@ -192,8 +192,8 @@ PluginBase.prototype._mergeNamedItems = function(arr1, arr2, key) {
PluginBase.prototype._mergeSingleItemOrProperty = PluginBase.prototype._mergeSingleItemOrProperty =
function(target, config, key, fullKey) { function(target, config, key, fullKey) {
var origValue = target[key]; const origValue = target[key];
var newValue = config[key]; const newValue = config[key];
if (!hasCompatibleType(origValue, newValue)) { if (!hasCompatibleType(origValue, newValue)) {
return 'Cannot merge values of incompatible types for the option `' + return 'Cannot merge values of incompatible types for the option `' +
@ -219,9 +219,9 @@ PluginBase.prototype._mergeArrays = function(target, config, keyPrefix) {
} }
// Use for(;;) to iterate over undefined items, for(in) would skip them. // Use for(;;) to iterate over undefined items, for(in) would skip them.
for (var ix = 0; ix < target.length; ix++) { for (let ix = 0; ix < target.length; ix++) {
var fullKey = keyPrefix + '[' + ix + ']'; const fullKey = keyPrefix + '[' + ix + ']';
var err = this._mergeSingleItemOrProperty(target, config, ix, fullKey); const err = this._mergeSingleItemOrProperty(target, config, ix, fullKey);
if (err) return err; if (err) return err;
} }
@ -244,10 +244,10 @@ function hasCompatibleType(origValue, newValue) {
} }
PluginBase.prototype.compile = function(context) { PluginBase.prototype.compile = function(context) {
var instructions; let instructions;
if (typeof this.buildInstructions === 'function') { if (typeof this.buildInstructions === 'function') {
var rootDir = this.options.rootDir; const rootDir = this.options.rootDir;
var config = context.configurations[this.name] || {}; const config = context.configurations[this.name] || {};
instructions = this.buildInstructions(context, rootDir, config); instructions = this.buildInstructions(context, rootDir, config);
} else { } else {
instructions = context.configurations[this.name]; instructions = context.configurations[this.name];
@ -265,12 +265,12 @@ PluginBase.prototype.compile = function(context) {
return undefined; return undefined;
}; };
var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/; const DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/;
function getConfigVariable(app, param, useEnvVars) { function getConfigVariable(app, param, useEnvVars) {
var configVariable = param; let configVariable = param;
var match = configVariable.match(DYNAMIC_CONFIG_PARAM); const match = configVariable.match(DYNAMIC_CONFIG_PARAM);
if (match) { if (match) {
var varName = match[1]; const varName = match[1];
if (useEnvVars && process.env[varName] !== undefined) { if (useEnvVars && process.env[varName] !== undefined) {
debug('Dynamic Configuration: Resolved via process.env: %s as %s', debug('Dynamic Configuration: Resolved via process.env: %s as %s',
process.env[varName], param); process.env[varName], param);
@ -278,7 +278,7 @@ function getConfigVariable(app, param, useEnvVars) {
} else if (app.get(varName) !== undefined) { } else if (app.get(varName) !== undefined) {
debug('Dynamic Configuration: Resolved via app.get(): %s as %s', debug('Dynamic Configuration: Resolved via app.get(): %s as %s',
app.get(varName), param); app.get(varName), param);
var appValue = app.get(varName); const appValue = app.get(varName);
configVariable = appValue; configVariable = appValue;
} else { } else {
// previously it returns the original string such as "${restApiRoot}" // previously it returns the original string such as "${restApiRoot}"
@ -296,8 +296,8 @@ function getConfigVariable(app, param, useEnvVars) {
} }
PluginBase.prototype.getUpdatedConfigObject = function(context, config, opts) { PluginBase.prototype.getUpdatedConfigObject = function(context, config, opts) {
var app = context.app; const app = context.app;
var useEnvVars = opts && opts.useEnvVars; const useEnvVars = opts && opts.useEnvVars;
function interpolateVariables(config) { function interpolateVariables(config) {
// config is a string and contains a config variable ('${var}') // config is a string and contains a config variable ('${var}')
@ -317,9 +317,9 @@ PluginBase.prototype.getUpdatedConfigObject = function(context, config, opts) {
return config; return config;
// recurse into object props // recurse into object props
var interpolated = {}; const interpolated = {};
Object.keys(config).forEach(function(configKey) { Object.keys(config).forEach(function(configKey) {
var value = config[configKey]; const value = config[configKey];
if (Array.isArray(value)) { if (Array.isArray(value)) {
interpolated[configKey] = value.map(interpolateVariables); interpolated[configKey] = value.map(interpolateVariables);
} else if (typeof value === 'string') { } else if (typeof value === 'string') {

View File

@ -1,17 +1,17 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var utils = require('./utils'); const utils = require('./utils');
var path = require('path'); const path = require('path');
var async = require('async'); const async = require('async');
var debug = require('debug')('loopback:boot:plugin-loader'); const debug = require('debug')('loopback:boot:plugin-loader');
var PluginBase = require('./plugin-base'); const PluginBase = require('./plugin-base');
var _ = require('lodash'); const _ = require('lodash');
module.exports = function(options) { module.exports = function(options) {
return new PluginScript(options); return new PluginScript(options);
@ -24,23 +24,23 @@ function PluginScript(options) {
util.inherits(PluginScript, PluginBase); util.inherits(PluginScript, PluginBase);
PluginScript.prototype.load = function(context) { PluginScript.prototype.load = function(context) {
var options = this.options; const options = this.options;
var appRootDir = options.rootDir; const appRootDir = options.rootDir;
// require directories // require directories
var pluginDirs = options.pluginDirs || []; // precedence let pluginDirs = options.pluginDirs || []; // precedence
pluginDirs = pluginDirs.concat(path.join(appRootDir, 'plugins')); pluginDirs = pluginDirs.concat(path.join(appRootDir, 'plugins'));
utils.resolveRelativePaths(pluginDirs, appRootDir); utils.resolveRelativePaths(pluginDirs, appRootDir);
var pluginScripts = options.pluginScripts || []; let pluginScripts = options.pluginScripts || [];
utils.resolveRelativePaths(pluginScripts, appRootDir); utils.resolveRelativePaths(pluginScripts, appRootDir);
pluginDirs.forEach(function(dir) { pluginDirs.forEach(function(dir) {
pluginScripts = pluginScripts.concat( pluginScripts = pluginScripts.concat(
utils.findScripts(dir, options.scriptExtensions) utils.findScripts(dir, options.scriptExtensions),
); );
var envdir = dir + '/' + options.env; const envdir = dir + '/' + options.env;
pluginScripts = pluginScripts.concat( pluginScripts = pluginScripts.concat(
utils.findScripts(envdir, options.scriptExtensions) utils.findScripts(envdir, options.scriptExtensions),
); );
}); });
@ -51,15 +51,15 @@ PluginScript.prototype.load = function(context) {
}; };
PluginScript.prototype.compile = function(context) { PluginScript.prototype.compile = function(context) {
var pluginScripts = context.configurations.pluginScripts; const pluginScripts = context.configurations.pluginScripts;
context.instructions = context.instructions || {}; context.instructions = context.instructions || {};
var plugins = context.instructions.pluginScripts = {}; const plugins = context.instructions.pluginScripts = {};
var self = this; const self = this;
pluginScripts.forEach(function(ps) { pluginScripts.forEach(function(ps) {
debug('Loading %s', ps); debug('Loading %s', ps);
var factory = require(ps); const factory = require(ps);
var handler = factory(self.options); const handler = factory(self.options);
var name = handler.name || path.basename(ps, '.js'); const name = handler.name || path.basename(ps, '.js');
debug('Loaded plugin name: %s', name); debug('Loaded plugin name: %s', name);
plugins[name] = handler; plugins[name] = handler;
}); });

View File

@ -1,15 +1,15 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var assert = require('assert'); const assert = require('assert');
var semver = require('semver'); const semver = require('semver');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var g = require('../globalize'); const g = require('../globalize');
module.exports = function(options) { module.exports = function(options) {
return new Application(options); return new Application(options);
@ -22,19 +22,19 @@ function Application(options) {
util.inherits(Application, PluginBase); util.inherits(Application, PluginBase);
function assertLoopBackVersion(app) { function assertLoopBackVersion(app) {
var RANGE = '2.x || 3.x'; const RANGE = '2.x || 3.x';
var loopback = app.loopback; const loopback = app.loopback;
// remove any pre-release tag from the version string, // remove any pre-release tag from the version string,
// because semver has special treatment of pre-release versions, // because semver has special treatment of pre-release versions,
// while loopback-boot treats pre-releases the same way as regular versions // while loopback-boot treats pre-releases the same way as regular versions
var version = (loopback.version || '1.0.0').replace(/-.*$/, ''); const version = (loopback.version || '1.0.0').replace(/-.*$/, '');
if (!semver.satisfies(version, RANGE)) { if (!semver.satisfies(version, RANGE)) {
var msg = g.f( const msg = g.f(
'The `app` is powered by an incompatible loopback version %s. ' + 'The `app` is powered by an incompatible loopback version %s. ' +
'Supported versions: %s', 'Supported versions: %s',
loopback.version || '(unknown)', loopback.version || '(unknown)',
RANGE RANGE,
); );
throw new Error(msg); throw new Error(msg);
} }
@ -47,7 +47,7 @@ function setEnv(app, env) {
function setHost(app, appConfig) { function setHost(app, appConfig) {
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var host = const host =
process.env.npm_config_host || process.env.npm_config_host ||
process.env.OPENSHIFT_SLS_IP || process.env.OPENSHIFT_SLS_IP ||
process.env.OPENSHIFT_NODEJS_IP || process.env.OPENSHIFT_NODEJS_IP ||
@ -65,7 +65,7 @@ function setHost(app, appConfig) {
function setPort(app, appConfig) { function setPort(app, appConfig) {
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var port = find([ const 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,
@ -80,7 +80,7 @@ function setPort(app, appConfig) {
}); });
if (port !== undefined) { if (port !== undefined) {
var portType = typeof port; const portType = typeof port;
assert(portType === 'string' || portType === 'number', assert(portType === 'string' || portType === 'number',
'app.port must be a string or number'); 'app.port must be a string or number');
app.set('port', port); app.set('port', port);
@ -92,7 +92,7 @@ function find(array, predicate) {
} }
function setApiRoot(app, appConfig) { function setApiRoot(app, appConfig) {
var restApiRoot = const restApiRoot =
appConfig.restApiRoot || appConfig.restApiRoot ||
app.get('restApiRoot') || app.get('restApiRoot') ||
'/api'; '/api';
@ -106,8 +106,8 @@ function setApiRoot(app, appConfig) {
} }
function applyAppConfig(app, appConfig) { function applyAppConfig(app, appConfig) {
for (var configKey in appConfig) { for (const configKey in appConfig) {
var cur = app.get(configKey); const cur = app.get(configKey);
if (cur === undefined || cur === null) { if (cur === undefined || cur === null) {
app.set(configKey, appConfig[configKey]); app.set(configKey, appConfig[configKey]);
} }
@ -115,10 +115,10 @@ function applyAppConfig(app, appConfig) {
} }
Application.prototype.starting = function(context) { Application.prototype.starting = function(context) {
var app = context.app; const app = context.app;
assertLoopBackVersion(app); assertLoopBackVersion(app);
var appConfig = context.instructions.application; const appConfig = context.instructions.application;
setEnv(app, context.instructions.env || this.options.env); setEnv(app, context.instructions.env || this.options.env);
setHost(app, appConfig); setHost(app, appConfig);
setPort(app, appConfig); setPort(app, appConfig);
@ -127,7 +127,7 @@ Application.prototype.starting = function(context) {
}; };
Application.prototype.started = function(context, done) { Application.prototype.started = function(context, done) {
var app = context.app; const app = context.app;
process.nextTick(function() { process.nextTick(function() {
app.emit('booted'); app.emit('booted');
done(); done();

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var utils = require('../utils'); const utils = require('../utils');
var path = require('path'); const path = require('path');
var async = require('async'); const async = require('async');
var debug = require('debug')('loopback:boot:script'); const debug = require('debug')('loopback:boot:script');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var _ = require('lodash'); const _ = require('lodash');
var g = require('../globalize'); const g = require('../globalize');
module.exports = function(options) { module.exports = function(options) {
return new Script(options); return new Script(options);
@ -25,23 +25,23 @@ function Script(options) {
util.inherits(Script, PluginBase); util.inherits(Script, PluginBase);
Script.prototype.load = function(context) { Script.prototype.load = function(context) {
var options = this.options; const options = this.options;
var appRootDir = options.rootDir; const appRootDir = options.rootDir;
// require directories // require directories
var bootDirs = options.bootDirs || []; // precedence let bootDirs = options.bootDirs || []; // precedence
bootDirs = bootDirs.concat(path.join(appRootDir, 'boot')); bootDirs = bootDirs.concat(path.join(appRootDir, 'boot'));
utils.resolveRelativePaths(bootDirs, appRootDir); utils.resolveRelativePaths(bootDirs, appRootDir);
var bootScripts = options.bootScripts || []; let bootScripts = options.bootScripts || [];
utils.resolveRelativePaths(bootScripts, appRootDir); utils.resolveRelativePaths(bootScripts, appRootDir);
bootDirs.forEach(function(dir) { bootDirs.forEach(function(dir) {
bootScripts = bootScripts.concat( bootScripts = bootScripts.concat(
utils.findScripts(dir, options.scriptExtensions) utils.findScripts(dir, options.scriptExtensions),
); );
var envdir = dir + '/' + options.env; const envdir = dir + '/' + options.env;
bootScripts = bootScripts.concat( bootScripts = bootScripts.concat(
utils.findScripts(envdir, options.scriptExtensions) utils.findScripts(envdir, options.scriptExtensions),
); );
}); });
@ -54,18 +54,18 @@ Script.prototype.load = function(context) {
}; };
Script.prototype.start = function(context, done) { Script.prototype.start = function(context, done) {
var app = context.app; const app = context.app;
var instructions = context.instructions[this.name]; const instructions = context.instructions[this.name];
runScripts(app, instructions, done); runScripts(app, instructions, done);
}; };
function runScripts(app, list, callback) { function runScripts(app, list, callback) {
list = list || []; list = list || [];
var functions = []; const functions = [];
list.forEach(function(filepath) { list.forEach(function(filepath) {
debug('Requiring script %s', filepath); debug('Requiring script %s', filepath);
try { try {
var exports = require(filepath); let exports = require(filepath);
if (exports.__esModule) exports = exports.default; if (exports.__esModule) exports = exports.default;
if (typeof exports === 'function') { if (typeof exports === 'function') {
debug('Exported function detected %s', filepath); debug('Exported function detected %s', filepath);
@ -82,7 +82,7 @@ function runScripts(app, list, callback) {
async.eachSeries(functions, function(f, done) { async.eachSeries(functions, function(f, done) {
debug('Running script %s', f.path); debug('Running script %s', f.path);
var cb = function(err) { let cb = function(err) {
debug('Async function %s %s', err ? 'failed' : 'finished', f.path); debug('Async function %s %s', err ? 'failed' : 'finished', f.path);
done(err); done(err);
// Make sure done() isn't called twice, e.g. if a script returns a // Make sure done() isn't called twice, e.g. if a script returns a
@ -90,7 +90,7 @@ function runScripts(app, list, callback) {
cb = function() {}; cb = function() {};
}; };
try { try {
var result = f.func(app, cb); const result = f.func(app, cb);
if (result && typeof result.then === 'function') { if (result && typeof result.then === 'function') {
result.then(function() { cb(); }, cb); result.then(function() { cb(); }, cb);
} else if (f.func.length < 2) { } else if (f.func.length < 2) {

View File

@ -1,17 +1,17 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var debug = require('debug')('loopback:boot:component'); const debug = require('debug')('loopback:boot:component');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var utils = require('../utils'); const utils = require('../utils');
var resolveAppScriptPath = utils.resolveAppScriptPath; const resolveAppScriptPath = utils.resolveAppScriptPath;
module.exports = function(options) { module.exports = function(options) {
return new Component(options); return new Component(options);
@ -40,11 +40,11 @@ Component.prototype.buildInstructions = function(context, rootDir, config) {
}; };
Component.prototype.start = function(context) { Component.prototype.start = function(context) {
var app = context.app; const app = context.app;
var self = this; const self = this;
context.instructions[this.name].forEach(function(data) { context.instructions[this.name].forEach(function(data) {
debug('Configuring component %j', data.sourceFile); debug('Configuring component %j', data.sourceFile);
var configFn = require(data.sourceFile); const configFn = require(data.sourceFile);
data.config = self.getUpdatedConfigObject(context, data.config, data.config = self.getUpdatedConfigObject(context, data.config,
{useEnvVars: true}); {useEnvVars: true});
configFn(app, data.config); configFn(app, data.config);

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var utils = require('../utils'); const utils = require('../utils');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var debug = require('debug')('loopback:boot:datasource'); const debug = require('debug')('loopback:boot:datasource');
module.exports = function(options) { module.exports = function(options) {
return new DataSource(options); return new DataSource(options);
@ -25,9 +25,9 @@ DataSource.prototype.getRootDir = function() {
}; };
DataSource.prototype.start = function(context) { DataSource.prototype.start = function(context) {
var app = context.app; const app = context.app;
var self = this; const self = this;
var lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES; const lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES;
utils.forEachKeyedObject(context.instructions[this.name], function(key, obj) { utils.forEachKeyedObject(context.instructions[this.name], function(key, obj) {
obj = self.getUpdatedConfigObject(context, obj, {useEnvVars: true}); obj = self.getUpdatedConfigObject(context, obj, {useEnvVars: true});
debug('Registering data source %s %j', key, obj); debug('Registering data source %s %j', key, obj);

View File

@ -1,22 +1,22 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var assert = require('assert'); const assert = require('assert');
var path = require('path'); const path = require('path');
var _ = require('lodash'); const _ = require('lodash');
var cloneDeepWith = _.cloneDeepWith; const cloneDeepWith = _.cloneDeepWith;
var cloneDeep = _.cloneDeep; const cloneDeep = _.cloneDeep;
var debug = require('debug')('loopback:boot:middleware'); const debug = require('debug')('loopback:boot:middleware');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var utils = require('../utils'); const utils = require('../utils');
var g = require('../globalize'); const g = require('../globalize');
var resolveAppScriptPath = utils.resolveAppScriptPath; const resolveAppScriptPath = utils.resolveAppScriptPath;
module.exports = function(options) { module.exports = function(options) {
return new Middleware(options); return new Middleware(options);
@ -33,7 +33,7 @@ Middleware.prototype.getRootDir = function() {
}; };
Middleware.prototype.merge = function(target, config, fileName) { Middleware.prototype.merge = function(target, config, fileName) {
var err, phase; let err, phase;
for (phase in config) { for (phase in config) {
if (phase in target) { if (phase in target) {
err = this.mergePhaseConfig(target[phase], config[phase], phase); err = this.mergePhaseConfig(target[phase], config[phase], phase);
@ -46,11 +46,11 @@ Middleware.prototype.merge = function(target, config, fileName) {
}; };
Middleware.prototype.mergePhaseConfig = function(target, config, phase) { Middleware.prototype.mergePhaseConfig = function(target, config, phase) {
var err, mw; let err, mw;
for (mw in config) { for (mw in config) {
if (mw in target) { if (mw in target) {
var targetMiddleware = target[mw]; const targetMiddleware = target[mw];
var configMiddleware = config[mw]; const configMiddleware = config[mw];
if (Array.isArray(targetMiddleware) && Array.isArray(configMiddleware)) { if (Array.isArray(targetMiddleware) && Array.isArray(configMiddleware)) {
// Both are arrays, combine them // Both are arrays, combine them
target[mw] = this._mergeNamedItems(targetMiddleware, configMiddleware); target[mw] = this._mergeNamedItems(targetMiddleware, configMiddleware);
@ -83,18 +83,18 @@ Middleware.prototype.mergePhaseConfig = function(target, config, phase) {
}; };
Middleware.prototype.buildInstructions = function(context, rootDir, config) { Middleware.prototype.buildInstructions = function(context, rootDir, config) {
var phasesNames = Object.keys(config); const phasesNames = Object.keys(config);
var middlewareList = []; const middlewareList = [];
phasesNames.forEach(function(phase) { phasesNames.forEach(function(phase) {
var phaseConfig = config[phase]; const phaseConfig = config[phase];
Object.keys(phaseConfig).forEach(function(middleware) { Object.keys(phaseConfig).forEach(function(middleware) {
var allConfigs = phaseConfig[middleware]; let allConfigs = phaseConfig[middleware];
if (!Array.isArray(allConfigs)) if (!Array.isArray(allConfigs))
allConfigs = [allConfigs]; allConfigs = [allConfigs];
allConfigs.forEach(function(config) { allConfigs.forEach(function(config) {
var resolved = resolveMiddlewarePath(rootDir, middleware, config); const resolved = resolveMiddlewarePath(rootDir, middleware, config);
// resolved.sourceFile will be false-y if an optional middleware // resolved.sourceFile will be false-y if an optional middleware
// is not resolvable. // is not resolvable.
// if a non-optional middleware is not resolvable, it will throw // if a non-optional middleware is not resolvable, it will throw
@ -105,16 +105,16 @@ Middleware.prototype.buildInstructions = function(context, rootDir, config) {
resolved.optional); resolved.optional);
} }
var middlewareConfig = cloneDeep(config); const middlewareConfig = cloneDeep(config);
middlewareConfig.phase = phase; middlewareConfig.phase = phase;
if (middlewareConfig.params) { if (middlewareConfig.params) {
middlewareConfig.params = resolveMiddlewareParams( middlewareConfig.params = resolveMiddlewareParams(
rootDir, middlewareConfig.params rootDir, middlewareConfig.params,
); );
} }
var item = { const item = {
sourceFile: resolved.sourceFile, sourceFile: resolved.sourceFile,
config: middlewareConfig, config: middlewareConfig,
}; };
@ -126,7 +126,7 @@ Middleware.prototype.buildInstructions = function(context, rootDir, config) {
}); });
}); });
var flattenedPhaseNames = phasesNames const flattenedPhaseNames = phasesNames
.map(function getBaseName(name) { .map(function getBaseName(name) {
return name.replace(/:[^:]+$/, ''); return name.replace(/:[^:]+$/, '');
}) })
@ -143,15 +143,15 @@ Middleware.prototype.buildInstructions = function(context, rootDir, config) {
}; };
function resolveMiddlewarePath(rootDir, middleware, config) { function resolveMiddlewarePath(rootDir, middleware, config) {
var resolved = { const resolved = {
optional: !!config.optional, optional: !!config.optional,
}; };
var segments = middleware.split('#'); const segments = middleware.split('#');
var pathName = segments[0]; let pathName = segments[0];
var fragment = segments[1]; const fragment = segments[1];
var middlewarePath = pathName; const middlewarePath = pathName;
var opts = { const opts = {
strict: true, strict: true,
optional: !!config.optional, optional: !!config.optional,
}; };
@ -165,7 +165,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
pathName = path.resolve(rootDir, pathName); pathName = path.resolve(rootDir, pathName);
} }
var resolveOpts = _.extend(opts, { const resolveOpts = _.extend(opts, {
// Workaround for strong-agent to allow probes to detect that // Workaround for strong-agent to allow probes to detect that
// strong-express-middleware was loaded: exclude the path to the // strong-express-middleware was loaded: exclude the path to the
// module main file from the source file path. // module main file from the source file path.
@ -175,7 +175,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
// node_modules/strong-express-metrics/index.js // node_modules/strong-express-metrics/index.js
fullResolve: false, fullResolve: false,
}); });
var sourceFile = resolveAppScriptPath(rootDir, middlewarePath, resolveOpts); const sourceFile = resolveAppScriptPath(rootDir, middlewarePath, resolveOpts);
if (!fragment) { if (!fragment) {
resolved.sourceFile = sourceFile; resolved.sourceFile = sourceFile;
@ -184,7 +184,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
// Try to require the module and check if <module>.<fragment> is a valid // Try to require the module and check if <module>.<fragment> is a valid
// function // function
var m = require(sourceFile); const m = require(sourceFile);
if (typeof m[fragment] === 'function') { if (typeof m[fragment] === 'function') {
resolved.sourceFile = sourceFile; resolved.sourceFile = sourceFile;
return resolved; return resolved;
@ -194,7 +194,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
* module/server/middleware/fragment * module/server/middleware/fragment
* module/middleware/fragment * module/middleware/fragment
*/ */
var candidates = [ const candidates = [
pathName + '/server/middleware/' + fragment, pathName + '/server/middleware/' + fragment,
pathName + '/middleware/' + fragment, pathName + '/middleware/' + fragment,
// TODO: [rfeng] Should we support the following flavors? // TODO: [rfeng] Should we support the following flavors?
@ -202,7 +202,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
// pathName + '/' + fragment // pathName + '/' + fragment
]; ];
var err, ix; let err, ix;
for (ix in candidates) { for (ix in candidates) {
try { try {
resolved.sourceFile = resolveAppScriptPath(rootDir, candidates[ix], opts); resolved.sourceFile = resolveAppScriptPath(rootDir, candidates[ix], opts);
@ -217,7 +217,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
} }
// Match values starting with `$!./` or `$!../` // Match values starting with `$!./` or `$!../`
var MIDDLEWARE_PATH_PARAM_REGEX = /^\$!(\.\/|\.\.\/)/; const MIDDLEWARE_PATH_PARAM_REGEX = /^\$!(\.\/|\.\.\/)/;
function resolveMiddlewareParams(rootDir, params) { function resolveMiddlewareParams(rootDir, params) {
return cloneDeepWith(params, function resolvePathParam(value) { return cloneDeepWith(params, function resolvePathParam(value) {
@ -230,20 +230,20 @@ function resolveMiddlewareParams(rootDir, params) {
} }
Middleware.prototype.start = function(context) { Middleware.prototype.start = function(context) {
var self = this; const self = this;
var app = context.app; const app = context.app;
var instructions = context.instructions.middleware; const instructions = context.instructions.middleware;
if (!instructions) { if (!instructions) {
// the browserified client does not support middleware // the browserified client does not support middleware
return; return;
} }
// Phases can be empty // Phases can be empty
var phases = instructions.phases || []; const phases = instructions.phases || [];
assert(Array.isArray(phases), assert(Array.isArray(phases),
'Middleware phases must be an array'); 'Middleware phases must be an array');
var middleware = instructions.middleware; const middleware = instructions.middleware;
assert(Array.isArray(middleware), assert(Array.isArray(middleware),
'Middleware must be an array'); 'Middleware must be an array');
@ -253,7 +253,7 @@ Middleware.prototype.start = function(context) {
middleware.forEach(function(data) { middleware.forEach(function(data) {
debug('Configuring middleware %j%s', data.sourceFile, debug('Configuring middleware %j%s', data.sourceFile,
data.fragment ? ('#' + data.fragment) : ''); data.fragment ? ('#' + data.fragment) : '');
var factory = require(data.sourceFile); let factory = require(data.sourceFile);
if (data.fragment) { if (data.fragment) {
factory = factory[data.fragment].bind(factory); factory = factory[data.fragment].bind(factory);
} }

View File

@ -1,23 +1,23 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var fs = require('fs'); const fs = require('fs');
var path = require('path'); const path = require('path');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var _ = require('lodash'); const _ = require('lodash');
var debug = require('debug')('loopback:boot:mixin'); const debug = require('debug')('loopback:boot:mixin');
var utils = require('../utils'); const utils = require('../utils');
var g = require('../globalize'); const g = require('../globalize');
var tryResolveAppPath = utils.tryResolveAppPath; const tryResolveAppPath = utils.tryResolveAppPath;
var getExcludedExtensions = utils.getExcludedExtensions; const getExcludedExtensions = utils.getExcludedExtensions;
var findScripts = utils.findScripts; const findScripts = utils.findScripts;
var FILE_EXTENSION_JSON = utils.FILE_EXTENSION_JSON; const FILE_EXTENSION_JSON = utils.FILE_EXTENSION_JSON;
module.exports = function(options) { module.exports = function(options) {
return new Mixin(options); return new Mixin(options);
@ -30,14 +30,14 @@ function Mixin(options) {
util.inherits(Mixin, PluginBase); util.inherits(Mixin, PluginBase);
Mixin.prototype.buildInstructions = function(context, rootDir, config) { Mixin.prototype.buildInstructions = function(context, rootDir, config) {
var modelsMeta = context.configurations.mixins._meta || {}; const modelsMeta = context.configurations.mixins._meta || {};
var modelInstructions = context.instructions.models; const modelInstructions = context.instructions.models;
var mixinSources = this.options.mixinSources || modelsMeta.mixins || const mixinSources = this.options.mixinSources || modelsMeta.mixins ||
['./mixins']; ['./mixins'];
var scriptExtensions = this.options.scriptExtensions || require.extensions; const scriptExtensions = this.options.scriptExtensions || require.extensions;
var mixinInstructions = buildAllMixinInstructions( const mixinInstructions = buildAllMixinInstructions(
rootDir, this.options, mixinSources, scriptExtensions, modelInstructions rootDir, this.options, mixinSources, scriptExtensions, modelInstructions,
); );
return mixinInstructions; return mixinInstructions;
@ -46,14 +46,14 @@ Mixin.prototype.buildInstructions = function(context, rootDir, config) {
function buildAllMixinInstructions(appRootDir, options, mixinSources, function buildAllMixinInstructions(appRootDir, options, mixinSources,
scriptExtensions, modelInstructions) { scriptExtensions, modelInstructions) {
// load mixins from `options.mixins` // load mixins from `options.mixins`
var sourceFiles = options.mixins || []; let sourceFiles = options.mixins || [];
var mixinDirs = options.mixinDirs || []; const mixinDirs = options.mixinDirs || [];
var instructionsFromMixins = loadMixins(sourceFiles, options.normalization); const instructionsFromMixins = loadMixins(sourceFiles, options.normalization);
// load mixins from `options.mixinDirs` // load mixins from `options.mixinDirs`
sourceFiles = findMixinDefinitions(appRootDir, mixinDirs, scriptExtensions); sourceFiles = findMixinDefinitions(appRootDir, mixinDirs, scriptExtensions);
if (sourceFiles === undefined) return; if (sourceFiles === undefined) return;
var instructionsFromMixinDirs = loadMixins(sourceFiles, const instructionsFromMixinDirs = loadMixins(sourceFiles,
options.normalization); options.normalization);
/* If `mixinDirs` and `mixinSources` have any directories in common, /* If `mixinDirs` and `mixinSources` have any directories in common,
@ -64,31 +64,31 @@ function buildAllMixinInstructions(appRootDir, options, mixinSources,
sourceFiles = findMixinDefinitions(appRootDir, mixinSources, sourceFiles = findMixinDefinitions(appRootDir, mixinSources,
scriptExtensions); scriptExtensions);
if (sourceFiles === undefined) return; if (sourceFiles === undefined) return;
var instructionsFromMixinSources = loadMixins(sourceFiles, let instructionsFromMixinSources = loadMixins(sourceFiles,
options.normalization); options.normalization);
// Fetch unique list of mixin names, used in models // Fetch unique list of mixin names, used in models
var modelMixins = fetchMixinNamesUsedInModelInstructions(modelInstructions); let modelMixins = fetchMixinNamesUsedInModelInstructions(modelInstructions);
modelMixins = _.uniq(modelMixins); modelMixins = _.uniq(modelMixins);
// Filter-in only mixins, that are used in models // Filter-in only mixins, that are used in models
instructionsFromMixinSources = filterMixinInstructionsUsingWhitelist( instructionsFromMixinSources = filterMixinInstructionsUsingWhitelist(
instructionsFromMixinSources, modelMixins instructionsFromMixinSources, modelMixins,
); );
var mixins = _.assign( const mixins = _.assign(
instructionsFromMixins, instructionsFromMixins,
instructionsFromMixinDirs, instructionsFromMixinDirs,
instructionsFromMixinSources instructionsFromMixinSources,
); );
return _.values(mixins); return _.values(mixins);
} }
function findMixinDefinitions(appRootDir, sourceDirs, scriptExtensions) { function findMixinDefinitions(appRootDir, sourceDirs, scriptExtensions) {
var files = []; let files = [];
sourceDirs.forEach(function(dir) { sourceDirs.forEach(function(dir) {
var path = tryResolveAppPath(appRootDir, dir); const path = tryResolveAppPath(appRootDir, dir);
if (!path) { if (!path) {
debug('Skipping unknown module source dir %j', dir); debug('Skipping unknown module source dir %j', dir);
return; return;
@ -99,15 +99,15 @@ function findMixinDefinitions(appRootDir, sourceDirs, scriptExtensions) {
} }
function loadMixins(sourceFiles, normalization) { function loadMixins(sourceFiles, normalization) {
var mixinInstructions = {}; const mixinInstructions = {};
sourceFiles.forEach(function(filepath) { sourceFiles.forEach(function(filepath) {
var dir = path.dirname(filepath); const dir = path.dirname(filepath);
var ext = path.extname(filepath); const ext = path.extname(filepath);
var name = path.basename(filepath, ext); let name = path.basename(filepath, ext);
var metafile = path.join(dir, name + FILE_EXTENSION_JSON); const metafile = path.join(dir, name + FILE_EXTENSION_JSON);
name = normalizeMixinName(name, normalization); name = normalizeMixinName(name, normalization);
var meta = {}; const meta = {};
meta.name = name; meta.name = name;
if (utils.fileExistsSync(metafile)) { if (utils.fileExistsSync(metafile)) {
// May overwrite name, not sourceFile // May overwrite name, not sourceFile
@ -129,10 +129,10 @@ function fetchMixinNamesUsedInModelInstructions(modelInstructions) {
} }
function filterMixinInstructionsUsingWhitelist(instructions, includeMixins) { function filterMixinInstructionsUsingWhitelist(instructions, includeMixins) {
var instructionKeys = Object.keys(instructions); const instructionKeys = Object.keys(instructions);
includeMixins = _.intersection(instructionKeys, includeMixins); includeMixins = _.intersection(instructionKeys, includeMixins);
var filteredInstructions = {}; const filteredInstructions = {};
instructionKeys.forEach(function(mixinName) { instructionKeys.forEach(function(mixinName) {
if (includeMixins.indexOf(mixinName) !== -1) { if (includeMixins.indexOf(mixinName) !== -1) {
filteredInstructions[mixinName] = instructions[mixinName]; filteredInstructions[mixinName] = instructions[mixinName];
@ -168,7 +168,7 @@ function normalizeMixinName(str, normalization) {
return normalization(str); return normalization(str);
} }
var err = new Error(g.f('Invalid normalization format - "%s"', const err = new Error(g.f('Invalid normalization format - "%s"',
normalization)); normalization));
err.code = 'INVALID_NORMALIZATION_FORMAT'; err.code = 'INVALID_NORMALIZATION_FORMAT';
throw err; throw err;
@ -176,18 +176,18 @@ function normalizeMixinName(str, normalization) {
} }
Mixin.prototype.starting = function(context) { Mixin.prototype.starting = function(context) {
var app = context.app; const app = context.app;
var instructions = context.instructions.mixins; const instructions = context.instructions.mixins;
var modelBuilder = (app.registry || app.loopback).modelBuilder; const modelBuilder = (app.registry || app.loopback).modelBuilder;
var BaseClass = app.loopback.Model; const BaseClass = app.loopback.Model;
var mixins = instructions || []; const mixins = instructions || [];
if (!modelBuilder.mixins || !mixins.length) return; if (!modelBuilder.mixins || !mixins.length) return;
mixins.forEach(function(obj) { mixins.forEach(function(obj) {
debug('Requiring mixin %s', obj.sourceFile); debug('Requiring mixin %s', obj.sourceFile);
var mixin = require(obj.sourceFile); const mixin = require(obj.sourceFile);
if (typeof mixin === 'function' || mixin.prototype instanceof BaseClass) { if (typeof mixin === 'function' || mixin.prototype instanceof BaseClass) {
debug('Defining mixin %s', obj.name); debug('Defining mixin %s', obj.name);

View File

@ -1,24 +1,24 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var assert = require('assert'); const assert = require('assert');
var util = require('util'); const util = require('util');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
var path = require('path'); const path = require('path');
var debug = require('debug')('loopback:boot:model'); const debug = require('debug')('loopback:boot:model');
var _ = require('lodash'); const _ = require('lodash');
var toposort = require('toposort'); const toposort = require('toposort');
var utils = require('../utils'); const utils = require('../utils');
var tryReadDir = utils.tryReadDir; const tryReadDir = utils.tryReadDir;
var assertIsValidConfig = utils.assertIsValidConfig; const assertIsValidConfig = utils.assertIsValidConfig;
var tryResolveAppPath = utils.tryResolveAppPath; const tryResolveAppPath = utils.tryResolveAppPath;
var fixFileExtension = utils.fixFileExtension; const fixFileExtension = utils.fixFileExtension;
var g = require('../globalize'); const g = require('../globalize');
module.exports = function(options) { module.exports = function(options) {
return new Model(options); return new Model(options);
@ -35,39 +35,42 @@ Model.prototype.getRootDir = function() {
}; };
Model.prototype.load = function(context) { Model.prototype.load = function(context) {
var config = PluginBase.prototype.load.apply(this, arguments); const config = PluginBase.prototype.load.apply(this, arguments);
assertIsValidModelConfig(config); assertIsValidModelConfig(config);
return config; return config;
}; };
Model.prototype.buildInstructions = function(context, rootDir, modelsConfig) { Model.prototype.buildInstructions = function(context, rootDir, modelsConfig) {
var modelsMeta = modelsConfig._meta || {}; const modelsMeta = modelsConfig._meta || {};
delete modelsConfig._meta; delete modelsConfig._meta;
context.configurations.mixins._meta = modelsMeta; context.configurations.mixins._meta = modelsMeta;
var modelSources = this.options.modelSources || modelsMeta.sources || const modelSources = this.options.modelSources || modelsMeta.sources ||
['./models']; ['./models'];
var modelInstructions = buildAllModelInstructions( const modelInstructions = buildAllModelInstructions(
rootDir, modelsConfig, modelSources, this.options.modelDefinitions, rootDir, modelsConfig, modelSources, this.options.modelDefinitions,
this.options.scriptExtensions this.options.scriptExtensions,
); );
return modelInstructions; return modelInstructions;
}; };
function buildAllModelInstructions(rootDir, modelsConfig, sources, function buildAllModelInstructions(rootDir, modelsConfig, sources,
modelDefinitions, scriptExtensions) { modelDefinitions, scriptExtensions) {
var registry = verifyModelDefinitions(rootDir, modelDefinitions, let registry = verifyModelDefinitions(rootDir, modelDefinitions,
scriptExtensions); scriptExtensions);
if (!registry) { if (!registry) {
registry = findModelDefinitions(rootDir, sources, scriptExtensions); registry = findModelDefinitions(rootDir, sources, scriptExtensions);
} }
var modelNamesToBuild = addAllBaseModels(registry, Object.keys(modelsConfig)); const modelNamesToBuild = addAllBaseModels(
registry,
Object.keys(modelsConfig),
);
var instructions = modelNamesToBuild const instructions = modelNamesToBuild
.map(function createModelInstructions(name) { .map(function createModelInstructions(name) {
var config = modelsConfig[name]; const config = modelsConfig[name];
var definition = registry[name] || {}; const definition = registry[name] || {};
debug('Using model "%s"\nConfiguration: %j\nDefinition %j', debug('Using model "%s"\nConfiguration: %j\nDefinition %j',
name, config, definition.definition); name, config, definition.definition);
@ -84,20 +87,20 @@ function buildAllModelInstructions(rootDir, modelsConfig, sources,
} }
function addAllBaseModels(registry, modelNames) { function addAllBaseModels(registry, modelNames) {
var result = []; const result = [];
var visited = {}; const visited = {};
while (modelNames.length) { while (modelNames.length) {
var name = modelNames.shift(); const name = modelNames.shift();
if (visited[name]) continue; if (visited[name]) continue;
visited[name] = true; visited[name] = true;
result.push(name); result.push(name);
var definition = registry[name] && registry[name].definition; const definition = registry[name] && registry[name].definition;
if (!definition) continue; if (!definition) continue;
var base = getBaseModelName(definition); const base = getBaseModelName(definition);
// ignore built-in models like User // ignore built-in models like User
if (!registry[base]) continue; if (!registry[base]) continue;
@ -118,14 +121,14 @@ function getBaseModelName(modelDefinition) {
function sortByInheritance(instructions) { function sortByInheritance(instructions) {
// create edges Base name -> Model name // create edges Base name -> Model name
var edges = instructions const edges = instructions
.map(function(inst) { .map(function(inst) {
return [getBaseModelName(inst.definition), inst.name]; return [getBaseModelName(inst.definition), inst.name];
}); });
var sortedNames = toposort(edges); const sortedNames = toposort(edges);
var instructionsByModelName = {}; const instructionsByModelName = {};
instructions.forEach(function(inst) { instructions.forEach(function(inst) {
instructionsByModelName[inst.name] = inst; instructionsByModelName[inst.name] = inst;
}); });
@ -146,14 +149,14 @@ function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
return undefined; return undefined;
} }
var registry = {}; const registry = {};
modelDefinitions.forEach(function(definition, idx) { modelDefinitions.forEach(function(definition, idx) {
if (definition.sourceFile) { if (definition.sourceFile) {
var fullPath = path.resolve(rootDir, definition.sourceFile); const fullPath = path.resolve(rootDir, definition.sourceFile);
definition.sourceFile = fixFileExtension( definition.sourceFile = fixFileExtension(
fullPath, fullPath,
tryReadDir(path.dirname(fullPath)), tryReadDir(path.dirname(fullPath)),
scriptExtensions scriptExtensions,
); );
if (!definition.sourceFile) { if (!definition.sourceFile) {
@ -168,7 +171,7 @@ function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
path.relative(rootDir, definition.sourceFile) : path.relative(rootDir, definition.sourceFile) :
'(no source file)'); '(no source file)');
var modelName = definition.definition.name; const modelName = definition.definition.name;
if (!modelName) { if (!modelName) {
debug('Skipping model definition without Model name ' + debug('Skipping model definition without Model name ' +
'(from options.modelDefinitions @ index %s)', '(from options.modelDefinitions @ index %s)',
@ -182,26 +185,26 @@ function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
} }
function findModelDefinitions(rootDir, sources, scriptExtensions) { function findModelDefinitions(rootDir, sources, scriptExtensions) {
var registry = {}; const registry = {};
sources.forEach(function(src) { sources.forEach(function(src) {
var srcDir = tryResolveAppPath(rootDir, src, {strict: false}); const srcDir = tryResolveAppPath(rootDir, src, {strict: false});
if (!srcDir) { if (!srcDir) {
debug('Skipping unknown module source dir %j', src); debug('Skipping unknown module source dir %j', src);
return; return;
} }
var files = tryReadDir(srcDir); const files = tryReadDir(srcDir);
files files
.filter(function(f) { .filter(function(f) {
return f[0] !== '_' && path.extname(f) === '.json'; return f[0] !== '_' && path.extname(f) === '.json';
}) })
.forEach(function(f) { .forEach(function(f) {
var fullPath = path.resolve(srcDir, f); const fullPath = path.resolve(srcDir, f);
var entry = loadModelDefinition(rootDir, fullPath, files, const entry = loadModelDefinition(rootDir, fullPath, files,
scriptExtensions); scriptExtensions);
var modelName = entry.definition.name; const modelName = entry.definition.name;
if (!modelName) { if (!modelName) {
debug('Skipping model definition without Model name: %s', debug('Skipping model definition without Model name: %s',
path.relative(srcDir, fullPath)); path.relative(srcDir, fullPath));
@ -215,12 +218,12 @@ function findModelDefinitions(rootDir, sources, scriptExtensions) {
} }
function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) { function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) {
var definition = require(jsonFile); const definition = require(jsonFile);
var basename = path.basename(jsonFile, path.extname(jsonFile)); const basename = path.basename(jsonFile, path.extname(jsonFile));
definition.name = definition.name || _.upperFirst(_.camelCase(basename)); definition.name = definition.name || _.upperFirst(_.camelCase(basename));
// find a matching file with a supported extension like `.js` or `.coffee` // find a matching file with a supported extension like `.js` or `.coffee`
var sourceFile = fixFileExtension(jsonFile, allFiles, scriptExtensions); const sourceFile = fixFileExtension(jsonFile, allFiles, scriptExtensions);
if (sourceFile === undefined) { if (sourceFile === undefined) {
debug('Model source code not found: %s', sourceFile); debug('Model source code not found: %s', sourceFile);
@ -238,26 +241,26 @@ function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) {
function assertIsValidModelConfig(config) { function assertIsValidModelConfig(config) {
assertIsValidConfig('model', config); assertIsValidConfig('model', config);
for (var name in config) { for (const name in config) {
var entry = config[name]; const entry = config[name];
var options = entry.options || {}; const options = entry.options || {};
var unsupported = entry.properties || const unsupported = entry.properties ||
entry.base || options.base || entry.base || options.base ||
entry.plural || options.plural; entry.plural || options.plural;
if (unsupported) { if (unsupported) {
throw new Error(g.f( throw new Error(g.f(
'The data in {{model-config.json}} ' + 'The data in {{model-config.json}} ' +
'is in the unsupported {{1.x}} format.' 'is in the unsupported {{1.x}} format.',
)); ));
} }
} }
} }
// Regular expression to match built-in loopback models // Regular expression to match built-in loopback models
var LOOPBACK_MODEL_REGEXP = new RegExp( const LOOPBACK_MODEL_REGEXP = new RegExp(
['', 'node_modules', 'loopback', '[^\\/\\\\]+', 'models', '[^\\/\\\\]+\\.js$'] ['', 'node_modules', 'loopback', '[^\\/\\\\]+', 'models', '[^\\/\\\\]+\\.js$']
.join('\\' + path.sep) .join('\\' + path.sep),
); );
function isBuiltinLoopBackModel(app, data) { function isBuiltinLoopBackModel(app, data) {
@ -265,19 +268,19 @@ function isBuiltinLoopBackModel(app, data) {
if (!app.loopback[data.name]) return false; if (!app.loopback[data.name]) return false;
// 2. Built-in models have a script file `loopback/{facet}/models/{name}.js` // 2. Built-in models have a script file `loopback/{facet}/models/{name}.js`
var srcFile = data.sourceFile; const srcFile = data.sourceFile;
return srcFile && return srcFile &&
LOOPBACK_MODEL_REGEXP.test(srcFile); LOOPBACK_MODEL_REGEXP.test(srcFile);
} }
Model.prototype.start = function(context) { Model.prototype.start = function(context) {
var app = context.app; const app = context.app;
var instructions = context.instructions[this.name]; const instructions = context.instructions[this.name];
var registry = app.registry || app.loopback; const registry = app.registry || app.loopback;
instructions.forEach(function(data) { instructions.forEach(function(data) {
var name = data.name; const name = data.name;
var model; let model;
if (!data.definition) { if (!data.definition) {
model = registry.getModel(name); model = registry.getModel(name);
@ -294,7 +297,7 @@ Model.prototype.start = function(context) {
model = registry.createModel(data.definition); model = registry.createModel(data.definition);
if (data.sourceFile) { if (data.sourceFile) {
debug('Loading customization script %s', data.sourceFile); debug('Loading customization script %s', data.sourceFile);
var code = require(data.sourceFile); const code = require(data.sourceFile);
if (typeof code === 'function') { if (typeof code === 'function') {
debug('Customizing model %s', name); debug('Customizing model %s', name);
code(model); code(model);

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var util = require('util'); const util = require('util');
var PluginBase = require('../plugin-base'); const PluginBase = require('../plugin-base');
module.exports = function(options) { module.exports = function(options) {
return new Swagger(options); return new Swagger(options);
@ -19,13 +19,13 @@ function Swagger(options) {
util.inherits(Swagger, PluginBase); util.inherits(Swagger, PluginBase);
Swagger.prototype.start = function(context) { Swagger.prototype.start = function(context) {
var app = context.app; const app = context.app;
var appConfig = context.instructions.application; const appConfig = context.instructions.application;
// disable token requirement for swagger, if available // disable token requirement for swagger, if available
var swagger = app.remotes().exports.swagger; const swagger = app.remotes().exports.swagger;
if (!swagger) return; if (!swagger) return;
var requireTokenForSwagger = appConfig.swagger && const requireTokenForSwagger = appConfig.swagger &&
appConfig.swagger.requireToken; appConfig.swagger.requireToken;
swagger.requireToken = requireTokenForSwagger || false; swagger.requireToken = requireTokenForSwagger || false;
}; };

View File

@ -1,17 +1,17 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var debug = require('debug')('loopback:boot'); const debug = require('debug')('loopback:boot');
var path = require('path'); const path = require('path');
var Module = require('module'); const Module = require('module');
var fs = require('fs'); const fs = require('fs');
var assert = require('assert'); const assert = require('assert');
var _ = require('lodash'); const _ = require('lodash');
var g = require('./globalize'); const g = require('./globalize');
exports.arrayToObject = arrayToObject; exports.arrayToObject = arrayToObject;
exports.tryReadDir = tryReadDir; exports.tryReadDir = tryReadDir;
@ -26,7 +26,7 @@ exports.tryResolveAppPath = tryResolveAppPath;
exports.forEachKeyedObject = forEachKeyedObject; exports.forEachKeyedObject = forEachKeyedObject;
exports.mergePhaseNameLists = mergePhaseNameLists; exports.mergePhaseNameLists = mergePhaseNameLists;
var FILE_EXTENSION_JSON = exports.FILE_EXTENSION_JSON = '.json'; const FILE_EXTENSION_JSON = exports.FILE_EXTENSION_JSON = '.json';
/** /**
* Find all javascript files (except for those prefixed with _) * Find all javascript files (except for those prefixed with _)
* and all directories. * and all directories.
@ -37,7 +37,7 @@ var FILE_EXTENSION_JSON = exports.FILE_EXTENSION_JSON = '.json';
function findScripts(dir, scriptExtensions) { function findScripts(dir, scriptExtensions) {
assert(dir, 'cannot require directory contents without directory name'); assert(dir, 'cannot require directory contents without directory name');
var files = tryReadDir(dir); const files = tryReadDir(dir);
scriptExtensions = scriptExtensions || require.extensions; scriptExtensions = scriptExtensions || require.extensions;
// sort files in lowercase alpha for linux // sort files in lowercase alpha for linux
@ -54,15 +54,15 @@ function findScripts(dir, scriptExtensions) {
} }
}); });
var results = []; const results = [];
files.forEach(function(filename) { files.forEach(function(filename) {
// ignore index.js and files prefixed with underscore // ignore index.js and files prefixed with underscore
if (filename === 'index.js' || filename[0] === '_') { if (filename === 'index.js' || filename[0] === '_') {
return; return;
} }
var filepath = path.resolve(path.join(dir, filename)); const filepath = path.resolve(path.join(dir, filename));
var stats = fs.statSync(filepath); const stats = fs.statSync(filepath);
// only require files supported by specified extensions // only require files supported by specified extensions
if (stats.isFile()) { if (stats.isFile()) {
@ -87,9 +87,13 @@ function tryReadDir() {
} }
function resolveRelativePaths(relativePaths, appRootDir) { function resolveRelativePaths(relativePaths, appRootDir) {
var resolveOpts = {strict: false}; const resolveOpts = {strict: false};
relativePaths.forEach(function(relativePath, k) { relativePaths.forEach(function(relativePath, k) {
var resolvedPath = tryResolveAppPath(appRootDir, relativePath, resolveOpts); const resolvedPath = tryResolveAppPath(
appRootDir,
relativePath,
resolveOpts,
);
if (resolvedPath !== undefined) { if (resolvedPath !== undefined) {
relativePaths[k] = resolvedPath; relativePaths[k] = resolvedPath;
} else { } else {
@ -121,28 +125,28 @@ function arrayToObject(array) {
function isPreferredExtension(filename, includeExtensions) { function isPreferredExtension(filename, includeExtensions) {
assert(!!includeExtensions, '"includeExtensions" argument is required'); assert(!!includeExtensions, '"includeExtensions" argument is required');
var ext = path.extname(filename); const ext = path.extname(filename);
return (ext in includeExtensions) && !(ext in getExcludedExtensions()); return (ext in includeExtensions) && !(ext in getExcludedExtensions());
} }
function fixFileExtension(filepath, files, scriptExtensions) { function fixFileExtension(filepath, files, scriptExtensions) {
var results = []; const results = [];
var otherFile; let otherFile;
/* Prefer coffee scripts over json */ /* Prefer coffee scripts over json */
if (scriptExtensions && isPreferredExtension(filepath, scriptExtensions)) { if (scriptExtensions && isPreferredExtension(filepath, scriptExtensions)) {
return filepath; return filepath;
} }
var basename = path.basename(filepath, FILE_EXTENSION_JSON); const basename = path.basename(filepath, FILE_EXTENSION_JSON);
var sourceDir = path.dirname(filepath); const sourceDir = path.dirname(filepath);
files.forEach(function(f) { files.forEach(function(f) {
otherFile = path.resolve(sourceDir, f); otherFile = path.resolve(sourceDir, f);
var stats = fs.statSync(otherFile); const stats = fs.statSync(otherFile);
if (stats.isFile()) { if (stats.isFile()) {
var otherFileExtension = path.extname(f); const otherFileExtension = path.extname(f);
if (!(otherFileExtension in getExcludedExtensions()) && if (!(otherFileExtension in getExcludedExtensions()) &&
path.basename(f, otherFileExtension) == basename) { path.basename(f, otherFileExtension) == basename) {
@ -156,9 +160,9 @@ function fixFileExtension(filepath, files, scriptExtensions) {
} }
function resolveAppPath(rootDir, relativePath, resolveOptions) { function resolveAppPath(rootDir, relativePath, resolveOptions) {
var resolvedPath = tryResolveAppPath(rootDir, relativePath, resolveOptions); const resolvedPath = tryResolveAppPath(rootDir, relativePath, resolveOptions);
if (resolvedPath === undefined && !resolveOptions.optional) { if (resolvedPath === undefined && !resolveOptions.optional) {
var err = new Error(g.f('Cannot resolve path "%s"', relativePath)); const err = new Error(g.f('Cannot resolve path "%s"', relativePath));
err.code = 'PATH_NOT_FOUND'; err.code = 'PATH_NOT_FOUND';
throw err; throw err;
} }
@ -166,19 +170,19 @@ function resolveAppPath(rootDir, relativePath, resolveOptions) {
} }
function resolveAppScriptPath(rootDir, relativePath, resolveOptions) { function resolveAppScriptPath(rootDir, relativePath, resolveOptions) {
var resolvedPath = resolveAppPath(rootDir, relativePath, resolveOptions); const resolvedPath = resolveAppPath(rootDir, relativePath, resolveOptions);
if (!resolvedPath) { if (!resolvedPath) {
return false; return false;
} }
var sourceDir = path.dirname(resolvedPath); const sourceDir = path.dirname(resolvedPath);
var files = tryReadDir(sourceDir); const files = tryReadDir(sourceDir);
var fixedFile = fixFileExtension(resolvedPath, files); const fixedFile = fixFileExtension(resolvedPath, files);
return (fixedFile === undefined ? resolvedPath : fixedFile); return (fixedFile === undefined ? resolvedPath : fixedFile);
} }
function tryResolveAppPath(rootDir, relativePath, resolveOptions) { function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
var fullPath; let fullPath;
var start = relativePath.substring(0, 2); const start = relativePath.substring(0, 2);
/* In order to retain backward compatibility, we need to support /* In order to retain backward compatibility, we need to support
* two ways how to treat values that are not relative nor absolute * two ways how to treat values that are not relative nor absolute
@ -189,7 +193,7 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
*/ */
resolveOptions = resolveOptions || {strict: true}; resolveOptions = resolveOptions || {strict: true};
var isModuleRelative = false; let isModuleRelative = false;
if (relativePath[0] === '/') { if (relativePath[0] === '/') {
fullPath = relativePath; fullPath = relativePath;
} else if (start === './' || start === '..') { } else if (start === './' || start === '..') {
@ -222,17 +226,17 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
// [ env.NODE_PATH values, $HOME/.node_modules, etc. ] // [ env.NODE_PATH values, $HOME/.node_modules, etc. ]
// Module._nodeModulePaths(rootDir) returns a list of paths like // Module._nodeModulePaths(rootDir) returns a list of paths like
// [ rootDir/node_modules, rootDir/../node_modules, etc. ] // [ rootDir/node_modules, rootDir/../node_modules, etc. ]
var modulePaths = Module.globalPaths const modulePaths = Module.globalPaths
.concat(Module._nodeModulePaths(rootDir)); .concat(Module._nodeModulePaths(rootDir));
fullPath = modulePaths fullPath = modulePaths
.map(function(candidateDir) { .map(function(candidateDir) {
var absPath = path.join(candidateDir, relativePath); const absPath = path.join(candidateDir, relativePath);
try { try {
// NOTE(bajtos) We need to create a proper String object here, // NOTE(bajtos) We need to create a proper String object here,
// otherwise we can't attach additional properties to it // otherwise we can't attach additional properties to it
/* jshint -W053 */ /* jshint -W053 */
var filePath = new String(require.resolve(absPath)); const filePath = new String(require.resolve(absPath));
filePath.unresolvedPath = absPath; filePath.unresolvedPath = absPath;
return filePath; return filePath;
} catch (err) { } catch (err) {
@ -310,8 +314,8 @@ function forEachKeyedObject(obj, fn) {
function mergePhaseNameLists(currentNames, namesToMerge) { function mergePhaseNameLists(currentNames, namesToMerge) {
if (!namesToMerge.length) return currentNames.slice(); if (!namesToMerge.length) return currentNames.slice();
var targetArray = currentNames.slice(); const targetArray = currentNames.slice();
var targetIx = targetArray.indexOf(namesToMerge[0]); let targetIx = targetArray.indexOf(namesToMerge[0]);
if (targetIx === -1) { if (targetIx === -1) {
// the first new item does not match any existing one // the first new item does not match any existing one
@ -321,21 +325,21 @@ function mergePhaseNameLists(currentNames, namesToMerge) {
} }
// merge (zip) two arrays // merge (zip) two arrays
for (var sourceIx = 1; sourceIx < namesToMerge.length; sourceIx++) { for (let sourceIx = 1; sourceIx < namesToMerge.length; sourceIx++) {
var valueToAdd = namesToMerge[sourceIx]; const valueToAdd = namesToMerge[sourceIx];
var previousValue = namesToMerge[sourceIx - 1]; const previousValue = namesToMerge[sourceIx - 1];
var existingIx = targetArray.indexOf(valueToAdd, targetIx); const existingIx = targetArray.indexOf(valueToAdd, targetIx);
if (existingIx === -1) { if (existingIx === -1) {
// A new phase - try to add it after the last one, // A new phase - try to add it after the last one,
// unless it was already registered // unless it was already registered
if (targetArray.indexOf(valueToAdd) !== -1) { if (targetArray.indexOf(valueToAdd) !== -1) {
var errMsg = g.f('Ordering conflict: cannot add "%s' + const errMsg = g.f('Ordering conflict: cannot add "%s' +
'" after "%s", because the opposite order was ' + '" after "%s", because the opposite order was ' +
' already specified', valueToAdd, previousValue); ' already specified', valueToAdd, previousValue);
throw new Error(errMsg); throw new Error(errMsg);
} }
var previousIx = targetArray.indexOf(previousValue); const previousIx = targetArray.indexOf(previousValue);
targetArray.splice(previousIx + 1, 0, valueToAdd); targetArray.splice(previousIx + 1, 0, valueToAdd);
} else { } else {
// An existing phase - move the pointer // An existing phase - move the pointer

View File

@ -1,9 +1,6 @@
{ {
"name": "loopback-boot", "name": "loopback-boot",
"version": "3.2.1", "version": "3.3.1",
"publishConfig": {
"tag": "next"
},
"description": "Convention-based bootstrapper for LoopBack applications", "description": "Convention-based bootstrapper for LoopBack applications",
"keywords": [ "keywords": [
"StrongLoop", "StrongLoop",
@ -16,7 +13,7 @@
"url": "https://github.com/strongloop/loopback-boot" "url": "https://github.com/strongloop/loopback-boot"
}, },
"engines": { "engines": {
"node": ">=6" "node": ">=8"
}, },
"main": "index.js", "main": "index.js",
"browser": "browser.js", "browser": "browser.js",
@ -29,25 +26,26 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"async": "^2.4.0", "async": "^2.4.0",
"bluebird": "^3.4.0", "bluebird": "^3.5.3",
"commondir": "^1.0.1", "commondir": "^1.0.1",
"debug": "^2.2.0", "debug": "^4.1.1",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"semver": "^5.1.0", "semver": "^5.1.0",
"strong-globalize": "^4.1.1", "strong-globalize": "^4.1.1",
"toposort": "^2.0.2" "toposort": "^2.0.2"
}, },
"devDependencies": { "devDependencies": {
"browserify": "^4.2.3", "browserify": "^16.2.3",
"chai": "^3.5.0", "chai": "^4.2.0",
"coffeeify": "^3.0.1",
"coffeescript": "^2.3.1", "coffeescript": "^2.3.1",
"coffeeify": "^2.0.1", "dirty-chai": "^2.0.1",
"dirty-chai": "^1.2.2", "eslint": "^6.6.0",
"eslint": "^5.2.0", "eslint-config-loopback": "^13.1.0",
"eslint-config-loopback": "^11.0.0", "fs-extra": "^7.0.1",
"fs-extra": "^3.0.1",
"loopback": "^3.0.0", "loopback": "^3.0.0",
"mocha": "^5.2.0", "mocha": "^5.2.0",
"supertest": "^3.0.0" "supertest": "^4.0.2"
} },
"author": "IBM Corp."
} }

View File

@ -1,22 +1,22 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var path = require('path'); const path = require('path');
var loopback = require('loopback'); const loopback = require('loopback');
var chai = require('chai'); const chai = require('chai');
var dirtyChai = require('dirty-chai'); const dirtyChai = require('dirty-chai');
var expect = chai.expect; const expect = chai.expect;
chai.use(dirtyChai); chai.use(dirtyChai);
const bootLoopBackApp = require('..'); const bootLoopBackApp = require('..');
describe('bootLoopBackApp', function() { describe('bootLoopBackApp', function() {
var app; let app;
beforeEach(function() { beforeEach(function() {
app = loopback(); app = loopback();
}); });

View File

@ -1,38 +1,43 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var path = require('path'); const path = require('path');
var loopback = require('loopback'); const loopback = require('loopback');
var chai = require('chai'); const chai = require('chai');
var dirtyChai = require('dirty-chai'); const dirtyChai = require('dirty-chai');
var expect = chai.expect; const expect = chai.expect;
chai.use(dirtyChai); chai.use(dirtyChai);
var Bootstrapper = require('../lib/bootstrapper'); const Bootstrapper = require('../lib/bootstrapper');
describe('Bootstrapper', function() { describe('Bootstrapper', function() {
var app; let app;
beforeEach(function() { beforeEach(function() {
app = loopback(); app = loopback();
process.bootFlags = []; process.bootFlags = [];
}); });
it('should honor options.phases', function(done) { it('should honor options.phases', function(done) {
var options = { const options = {
app: app, app: app,
appRootDir: path.join(__dirname, './fixtures/simple-app'), appRootDir: path.join(__dirname, './fixtures/simple-app'),
phases: ['load'], phases: ['load'],
}; };
var bootstrapper = new Bootstrapper(options); const bootstrapper = new Bootstrapper(options);
var context = { const context = {
app: app, app: app,
}; };
bootstrapper.run(context, function(err) { bootstrapper.run(context, function(err) {
if (err) return done(err); if (err) return done(err);
var configs = context.configurations; const configs = context.configurations;
expect(configs.application, 'application').to.be.an('object'); expect(configs.application, 'application').to.be.an('object');
expect(configs.bootScripts, 'bootScripts').to.be.an('array'); expect(configs.bootScripts, 'bootScripts').to.be.an('array');
expect(configs.middleware, 'middleware').to.be.an('object'); expect(configs.middleware, 'middleware').to.be.an('object');
@ -45,22 +50,22 @@ describe('Bootstrapper', function() {
}); });
it('should honor options.plugins', function(done) { it('should honor options.plugins', function(done) {
var options = { const options = {
app: app, app: app,
appRootDir: path.join(__dirname, './fixtures/simple-app'), appRootDir: path.join(__dirname, './fixtures/simple-app'),
plugins: ['application', 'boot-script'], plugins: ['application', 'boot-script'],
}; };
var bootstrapper = new Bootstrapper(options); const bootstrapper = new Bootstrapper(options);
var context = { const context = {
app: app, app: app,
}; };
bootstrapper.run(context, function(err) { bootstrapper.run(context, function(err) {
if (err) return done(err); if (err) return done(err);
var configs = context.configurations; const configs = context.configurations;
var instructions = context.instructions; const instructions = context.instructions;
expect(configs.application, 'application').to.be.an('object'); expect(configs.application, 'application').to.be.an('object');
expect(configs.middleware, 'middleware').to.be.undefined(); expect(configs.middleware, 'middleware').to.be.undefined();
expect(configs.models, 'models').to.be.undefined(); expect(configs.models, 'models').to.be.undefined();
@ -89,15 +94,15 @@ describe('Bootstrapper', function() {
it('searches boot file extensions specified in options.scriptExtensions', it('searches boot file extensions specified in options.scriptExtensions',
function(done) { function(done) {
var options = { const options = {
app: app, app: app,
appRootDir: path.join(__dirname, './fixtures/simple-app'), appRootDir: path.join(__dirname, './fixtures/simple-app'),
scriptExtensions: ['.customjs', '.customjs2'], scriptExtensions: ['.customjs', '.customjs2'],
}; };
var bootstrapper = new Bootstrapper(options); const bootstrapper = new Bootstrapper(options);
var context = { const context = {
app: app, app: app,
}; };

View File

@ -1,21 +1,22 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var boot = require('../'); const boot = require('../');
var async = require('async'); const async = require('async');
var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox; const exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox;
var fs = require('fs'); const packageFilter = require('./helpers/browserify').packageFilter;
var path = require('path'); const fs = require('fs');
var expect = require('chai').expect; const path = require('path');
var browserify = require('browserify'); const expect = require('chai').expect;
var sandbox = require('./helpers/sandbox'); const browserify = require('browserify');
var vm = require('vm'); const sandbox = require('./helpers/sandbox');
var createBrowserLikeContext = require('./helpers/browser').createContext; const vm = require('vm');
var printContextLogs = require('./helpers/browser').printContextLogs; const createBrowserLikeContext = require('./helpers/browser').createContext;
const printContextLogs = require('./helpers/browser').printContextLogs;
describe('browser support for multiple apps', function() { describe('browser support for multiple apps', function() {
this.timeout(60000); // 60s to give browserify enough time to finish this.timeout(60000); // 60s to give browserify enough time to finish
@ -23,10 +24,10 @@ describe('browser support for multiple apps', function() {
beforeEach(sandbox.reset); beforeEach(sandbox.reset);
it('has API for bundling and booting multiple apps', function(done) { it('has API for bundling and booting multiple apps', function(done) {
var app1Dir = path.resolve(__dirname, './fixtures/browser-app'); const app1Dir = path.resolve(__dirname, './fixtures/browser-app');
var app2Dir = path.resolve(__dirname, './fixtures/browser-app-2'); const app2Dir = path.resolve(__dirname, './fixtures/browser-app-2');
var apps = [ const apps = [
{ {
appDir: app1Dir, appDir: app1Dir,
appFile: './app.js', appFile: './app.js',
@ -43,9 +44,9 @@ describe('browser support for multiple apps', function() {
browserifyTestApps(apps, function(err, bundlePath) { browserifyTestApps(apps, function(err, bundlePath) {
if (err) return done(err); if (err) return done(err);
var bundledApps = executeBundledApps(bundlePath, apps, function(err) { const bundledApps = executeBundledApps(bundlePath, apps, function(err) {
var app1 = bundledApps.defaultApp; const app1 = bundledApps.defaultApp;
var app2 = bundledApps.browserApp2; const app2 = bundledApps.browserApp2;
expect(app1.settings).to.have.property('custom-key', 'custom-value'); expect(app1.settings).to.have.property('custom-key', 'custom-value');
expect(Object.keys(app1.models)).to.include('Customer'); expect(Object.keys(app1.models)).to.include('Customer');
@ -63,22 +64,23 @@ describe('browser support for multiple apps', function() {
}); });
function browserifyTestApps(apps, next) { function browserifyTestApps(apps, next) {
var b = browserify({ const b = browserify({
debug: true, debug: true,
basedir: path.resolve(__dirname, './fixtures'), basedir: path.resolve(__dirname, './fixtures'),
packageFilter,
}); });
var bundles = []; const bundles = [];
for (var i in apps) { for (const i in apps) {
var appDir = apps[i].appDir; const appDir = apps[i].appDir;
var appFile = apps[i].appFile; let appFile = apps[i].appFile;
var moduleName = apps[i].moduleName; const moduleName = apps[i].moduleName;
var appId = apps[i].appId; const appId = apps[i].appId;
appFile = path.join(appDir, appFile); appFile = path.join(appDir, appFile);
b.require(appFile, {expose: moduleName}); b.require(appFile, {expose: moduleName});
var opts = appDir; let opts = appDir;
if (appId) { if (appId) {
opts = { opts = {
appId: appId, appId: appId,
@ -95,21 +97,21 @@ function browserifyTestApps(apps, next) {
} }
function executeBundledApps(bundlePath, apps, done) { function executeBundledApps(bundlePath, apps, done) {
var code = fs.readFileSync(bundlePath); const code = fs.readFileSync(bundlePath);
var context = createBrowserLikeContext(); const context = createBrowserLikeContext();
vm.runInContext(code, context, bundlePath); vm.runInContext(code, context, bundlePath);
var ids = []; const ids = [];
var script = 'var apps = {};\n'; let script = 'var apps = {};\n';
for (var i in apps) { for (const i in apps) {
var moduleName = apps[i].moduleName; const moduleName = apps[i].moduleName;
var id = apps[i].appId || 'defaultApp'; const id = apps[i].appId || 'defaultApp';
ids.push(id); ids.push(id);
script += 'apps.' + id + ' = require("' + moduleName + '");\n'; script += 'apps.' + id + ' = require("' + moduleName + '");\n';
} }
script += 'apps;\n'; script += 'apps;\n';
var appsInContext = vm.runInContext(script, context); const appsInContext = vm.runInContext(script, context);
async.each(ids, function(id, done) { async.each(ids, function(id, done) {
appsInContext[id].once('booted', function() { appsInContext[id].once('booted', function() {
done(); done();

View File

@ -1,36 +1,39 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var boot = require('../'); const boot = require('../');
var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox; const exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox;
var fs = require('fs'); const packageFilter = require('./helpers/browserify').packageFilter;
var path = require('path'); const fs = require('fs');
var expect = require('chai').expect; const path = require('path');
var browserify = require('browserify'); const expect = require('chai').expect;
var sandbox = require('./helpers/sandbox'); const browserify = require('browserify');
var vm = require('vm'); const sandbox = require('./helpers/sandbox');
var createBrowserLikeContext = require('./helpers/browser').createContext; const vm = require('vm');
var printContextLogs = require('./helpers/browser').printContextLogs; const createBrowserLikeContext = require('./helpers/browser').createContext;
const printContextLogs = require('./helpers/browser').printContextLogs;
var compileStrategies = { const compileStrategies = {
default: function(appDir) { default: function(appDir) {
var b = browserify({ const b = browserify({
basedir: appDir, basedir: appDir,
debug: true, debug: true,
packageFilter,
}); });
b.require('./app.js', {expose: 'browser-app'}); b.require('./app.js', {expose: 'browser-app'});
return b; return b;
}, },
coffee: function(appDir) { coffee: function(appDir) {
var b = browserify({ const b = browserify({
basedir: appDir, basedir: appDir,
extensions: ['.coffee'], extensions: ['.coffee'],
debug: true, debug: true,
packageFilter,
}); });
b.transform('coffeeify'); b.transform('coffeeify');
@ -45,19 +48,19 @@ describe('browser support', function() {
beforeEach(sandbox.reset); beforeEach(sandbox.reset);
it('has API for bundling and executing boot instructions', function(done) { it('has API for bundling and executing boot instructions', function(done) {
var appDir = path.resolve(__dirname, './fixtures/browser-app'); const appDir = path.resolve(__dirname, './fixtures/browser-app');
browserifyTestApp(appDir, function(err, bundlePath) { browserifyTestApp(appDir, function(err, bundlePath) {
if (err) return done(err); if (err) return done(err);
var app = executeBundledApp(bundlePath, function(err) { const app = executeBundledApp(bundlePath, function(err) {
if (err) return done(err); if (err) return done(err);
// configured in fixtures/browser-app/boot/configure.js // configured in fixtures/browser-app/boot/configure.js
expect(app.settings).to.have.property('custom-key', 'custom-value'); expect(app.settings).to.have.property('custom-key', 'custom-value');
expect(Object.keys(app.models)).to.include('Customer'); expect(Object.keys(app.models)).to.include('Customer');
expect(app.models.Customer.settings).to.have.property( expect(app.models.Customer.settings).to.have.property(
'_customized', '_customized',
'Customer' 'Customer',
); );
// configured in fixtures/browser-app/component-config.json // configured in fixtures/browser-app/component-config.json
@ -69,17 +72,17 @@ describe('browser support', function() {
}); });
it('loads mixins', function(done) { it('loads mixins', function(done) {
var appDir = path.resolve(__dirname, './fixtures/browser-app'); const appDir = path.resolve(__dirname, './fixtures/browser-app');
var options = { const options = {
appRootDir: appDir, appRootDir: appDir,
}; };
browserifyTestApp(options, function(err, bundlePath) { browserifyTestApp(options, function(err, bundlePath) {
if (err) return done(err); if (err) return done(err);
var app = executeBundledApp(bundlePath, function(err) { const app = executeBundledApp(bundlePath, function(err) {
var modelBuilder = app.registry.modelBuilder; const modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins; const registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['TimeStamps']); expect(Object.keys(registry)).to.eql(['TimeStamps']);
expect(app.models.Customer.timeStampsMixin).to.eql(true); expect(app.models.Customer.timeStampsMixin).to.eql(true);
@ -92,18 +95,18 @@ describe('browser support', function() {
// add coffee-script to require.extensions // add coffee-script to require.extensions
require('coffeescript/register'); require('coffeescript/register');
var appDir = path.resolve(__dirname, './fixtures/coffee-app'); const appDir = path.resolve(__dirname, './fixtures/coffee-app');
browserifyTestApp(appDir, 'coffee', function(err, bundlePath) { browserifyTestApp(appDir, 'coffee', function(err, bundlePath) {
if (err) return done(err); if (err) return done(err);
var app = executeBundledApp(bundlePath, function(err) { const app = executeBundledApp(bundlePath, function(err) {
// configured in fixtures/browser-app/boot/configure.coffee // configured in fixtures/browser-app/boot/configure.coffee
expect(app.settings).to.have.property('custom-key', 'custom-value'); expect(app.settings).to.have.property('custom-key', 'custom-value');
expect(Object.keys(app.models)).to.include('Customer'); expect(Object.keys(app.models)).to.include('Customer');
expect(app.models.Customer.settings).to.have.property( expect(app.models.Customer.settings).to.have.property(
'_customized', '_customized',
'Customer' 'Customer',
); );
done(); done();
}); });
@ -119,8 +122,8 @@ function browserifyTestApp(options, strategy, next) {
} }
if (!strategy) strategy = 'default'; if (!strategy) strategy = 'default';
var appDir = typeof options === 'object' ? options.appRootDir : options; const appDir = typeof options === 'object' ? options.appRootDir : options;
var b = compileStrategies[strategy](appDir); const b = compileStrategies[strategy](appDir);
boot.compileToBrowserify(options, b, function(err) { boot.compileToBrowserify(options, b, function(err) {
exportBrowserifyToFile(b, 'browser-app-bundle.js', next); exportBrowserifyToFile(b, 'browser-app-bundle.js', next);
@ -128,10 +131,10 @@ function browserifyTestApp(options, strategy, next) {
} }
function executeBundledApp(bundlePath, done) { function executeBundledApp(bundlePath, done) {
var code = fs.readFileSync(bundlePath); const code = fs.readFileSync(bundlePath);
var context = createBrowserLikeContext(); const context = createBrowserLikeContext();
vm.runInContext(code, context, bundlePath); vm.runInContext(code, context, bundlePath);
var app = vm.runInContext('require("browser-app")', context); const app = vm.runInContext('require("browser-app")', context);
app.once('booted', function(err) { app.once('booted', function(err) {
printContextLogs(context); printContextLogs(context);
done(err, app); done(err, app);

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,31 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var async = require('async'); const async = require('async');
var boot = require('../'); const boot = require('../');
var path = require('path'); const path = require('path');
var loopback = require('loopback'); const loopback = require('loopback');
var assert = require('assert'); const assert = require('assert');
var chai = require('chai'); const chai = require('chai');
var dirtyChai = require('dirty-chai'); const dirtyChai = require('dirty-chai');
var expect = chai.expect; const expect = chai.expect;
chai.use(dirtyChai); chai.use(dirtyChai);
var fs = require('fs-extra'); const fs = require('fs-extra');
var sandbox = require('./helpers/sandbox'); const sandbox = require('./helpers/sandbox');
var appdir = require('./helpers/appdir'); const appdir = require('./helpers/appdir');
var supertest = require('supertest'); const supertest = require('supertest');
var os = require('os'); const os = require('os');
var SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-app'); const SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-app');
var ENV_APP = path.join(__dirname, 'fixtures', 'env-app'); const ENV_APP = path.join(__dirname, 'fixtures', 'env-app');
var app; let app;
describe('executor', function() { describe('executor', function() {
beforeEach(sandbox.reset); beforeEach(sandbox.reset);
@ -43,7 +43,7 @@ describe('executor', function() {
delete process.bootFlags; delete process.bootFlags;
}); });
var dummyInstructions = someInstructions({ const dummyInstructions = someInstructions({
application: { application: {
port: 0, port: 0,
host: '127.0.0.1', host: '127.0.0.1',
@ -134,7 +134,7 @@ describe('executor', function() {
expect(app.models.Customer).to.exist(); expect(app.models.Customer).to.exist();
expect(app.models.Customer.settings._customized).to.be.equal('Customer'); expect(app.models.Customer.settings._customized).to.be.equal('Customer');
var UserModel = app.registry.getModel('User'); const UserModel = app.registry.getModel('User');
expect(UserModel.settings._customized).to.equal('Base'); expect(UserModel.settings._customized).to.equal('Base');
done(); done();
}); });
@ -232,7 +232,7 @@ describe('executor', function() {
}); });
it('throws on bad require() call inside boot script', function(done) { it('throws on bad require() call inside boot script', function(done) {
var file = appdir.writeFileSync('boot/badScript.js', const file = appdir.writeFileSync('boot/badScript.js',
'require("doesnt-exist"); module.exports = {};'); 'require("doesnt-exist"); module.exports = {};');
boot.execute(app, someInstructions({bootScripts: [file]}), boot.execute(app, someInstructions({bootScripts: [file]}),
@ -261,7 +261,7 @@ describe('executor', function() {
// loopback-datasource-juggler quirk: // loopback-datasource-juggler quirk:
// Model.dataSources has modelBuilder as the default value, // Model.dataSources has modelBuilder as the default value,
// therefore it's not enough to assert a false-y value // therefore it's not enough to assert a false-y value
var actual = loopback.Email.dataSource instanceof loopback.DataSource ? const actual = loopback.Email.dataSource instanceof loopback.DataSource ?
'attached' : 'not attached'; 'attached' : 'not attached';
expect(actual).to.equal('not attached'); expect(actual).to.equal('not attached');
done(); done();
@ -269,10 +269,10 @@ describe('executor', function() {
}); });
it('skips definition of already defined LoopBack models', function(done) { it('skips definition of already defined LoopBack models', function(done) {
var builtinModel = { const builtinModel = {
name: 'User', name: 'User',
definition: fs.readJsonSync( definition: fs.readJsonSync(
require.resolve('loopback/common/models/user.json') require.resolve('loopback/common/models/user.json'),
), ),
config: {dataSource: 'db'}, config: {dataSource: 'db'},
sourceFile: require.resolve('loopback/common/models/user.js'), sourceFile: require.resolve('loopback/common/models/user.js'),
@ -412,7 +412,7 @@ describe('executor', function() {
}); });
describe('for mixins', function() { describe('for mixins', function() {
var options; let options;
beforeEach(function() { beforeEach(function() {
appdir.writeFileSync('custom-mixins/example.js', appdir.writeFileSync('custom-mixins/example.js',
'module.exports = ' + 'module.exports = ' +
@ -436,8 +436,8 @@ describe('executor', function() {
options.mixinDirs = ['./custom-mixins']; options.mixinDirs = ['./custom-mixins'];
boot(app, options, function(err) { boot(app, options, function(err) {
if (err) return done(err); if (err) return done(err);
var modelBuilder = app.registry.modelBuilder; const modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins; const registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']); expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
done(); done();
}); });
@ -449,8 +449,8 @@ describe('executor', function() {
boot(app, options, function(err) { boot(app, options, function(err) {
if (err) return done(err); if (err) return done(err);
var modelBuilder = app.registry.modelBuilder; const modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins; const registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']); expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
done(); done();
}); });
@ -581,7 +581,7 @@ describe('executor', function() {
}); });
it('should respect named pipes port values in ENV', function(done) { it('should respect named pipes port values in ENV', function(done) {
var NAMED_PORT = '\\.\\pipe\\test'; const NAMED_PORT = '\\.\\pipe\\test';
process.env.PORT = NAMED_PORT; process.env.PORT = NAMED_PORT;
boot.execute(app, someInstructions({application: {port: 3000}}), boot.execute(app, someInstructions({application: {port: 3000}}),
function(err) { function(err) {
@ -627,8 +627,7 @@ describe('executor', function() {
it('dynamic variable from `env var` should have' + it('dynamic variable from `env var` should have' +
' precedence over app.get()', function(done) { ' precedence over app.get()', function(done) {
process.env.restApiRoot = '/url-from-env-var'; process.env.restApiRoot = '/url-from-env-var';
var bootInstructions; const bootInstructions = simpleMiddlewareConfig('routes',
bootInstructions = simpleMiddlewareConfig('routes',
{path: '${restApiRoot}'}); {path: '${restApiRoot}'});
bootInstructions.application = {restApiRoot: '/url-from-config'}; bootInstructions.application = {restApiRoot: '/url-from-config'};
boot.execute(app, someInstructions(bootInstructions), function(err) { boot.execute(app, someInstructions(bootInstructions), function(err) {
@ -665,7 +664,7 @@ describe('executor', function() {
supertest(app).get('/').end(function(err, res) { supertest(app).get('/').end(function(err, res) {
if (err) return done(err); if (err) return done(err);
expect(res.body.paths).to.eql( expect(res.body.paths).to.eql(
[app.get('restApiRoot')] [app.get('restApiRoot')],
); );
done(); done();
}); });
@ -721,10 +720,10 @@ describe('executor', function() {
}); });
it('should not parse invalid config variables', function(done) { it('should not parse invalid config variables', function(done) {
var invalidDataTypes = [undefined, function() { const invalidDataTypes = [undefined, function() {
}]; }];
async.each(invalidDataTypes, function(invalidDataType, cb) { async.each(invalidDataTypes, function(invalidDataType, cb) {
var config = simpleMiddlewareConfig('routes', { const config = simpleMiddlewareConfig('routes', {
path: invalidDataType, path: invalidDataType,
}); });
boot.execute(app, config, function(err) { boot.execute(app, config, function(err) {
@ -742,7 +741,7 @@ describe('executor', function() {
}); });
it('should parse valid config variables', function(done) { it('should parse valid config variables', function(done) {
var config = simpleMiddlewareConfig('routes', { const config = simpleMiddlewareConfig('routes', {
props: ['a', '${vVar}', 1, true, function() { props: ['a', '${vVar}', 1, true, function() {
}, {x: 1, y: '${y}'}], }, {x: 1, y: '${y}'}],
}); });
@ -759,11 +758,11 @@ describe('executor', function() {
}); });
it('should preserve object prototypes', function(done) { it('should preserve object prototypes', function(done) {
var config = simpleMiddlewareConfig( const config = simpleMiddlewareConfig(
'routes', 'routes',
// IMPORTANT we need more than one item to trigger the original issue // IMPORTANT we need more than one item to trigger the original issue
[/^\/foobar/, /^\/another/], [/^\/foobar/, /^\/another/],
{} {},
); );
boot.execute(app, config, function(err) { boot.execute(app, config, function(err) {
if (err) return done(err); if (err) return done(err);
@ -783,7 +782,7 @@ describe('executor', function() {
it('should parse a simple config variable', function(done) { it('should parse a simple config variable', function(done) {
boot.execute(app, simpleComponentConfig( boot.execute(app, simpleComponentConfig(
{path: '${restApiRoot}'} {path: '${restApiRoot}'},
), function(err) { ), function(err) {
if (err) return done(err); if (err) return done(err);
@ -796,12 +795,12 @@ describe('executor', function() {
}); });
it('should parse config from `env-var` and `config`', function(done) { it('should parse config from `env-var` and `config`', function(done) {
var bootInstructions = simpleComponentConfig( const bootInstructions = simpleComponentConfig(
{ {
path: '${restApiRoot}', path: '${restApiRoot}',
fromConfig: '${DYNAMIC_CONFIG}', fromConfig: '${DYNAMIC_CONFIG}',
fromEnvVar: '${DYNAMIC_ENVVAR}', fromEnvVar: '${DYNAMIC_ENVVAR}',
} },
); );
// result should get value from config.json // result should get value from config.json
@ -821,8 +820,8 @@ describe('executor', function() {
}); });
it('`env-var` should have precedence over `config`', function(done) { it('`env-var` should have precedence over `config`', function(done) {
var key = 'DYNAMIC_VARIABLE'; const key = 'DYNAMIC_VARIABLE';
var bootInstructions = simpleComponentConfig({ const bootInstructions = simpleComponentConfig({
path: '${restApiRoot}', path: '${restApiRoot}',
isDynamic: '${' + key + '}', isDynamic: '${' + key + '}',
}); });
@ -841,7 +840,7 @@ describe('executor', function() {
it('should parse multiple config variables', function(done) { it('should parse multiple config variables', function(done) {
boot.execute(app, simpleComponentConfig( boot.execute(app, simpleComponentConfig(
{path: '${restApiRoot}', env: '${env}'} {path: '${restApiRoot}', env: '${env}'},
), function(err) { ), function(err) {
if (err) return done(err); if (err) return done(err);
@ -856,14 +855,14 @@ describe('executor', function() {
it('should parse config variables in an array', function(done) { it('should parse config variables in an array', function(done) {
boot.execute(app, simpleComponentConfig( boot.execute(app, simpleComponentConfig(
{paths: ['${restApiRoot}']} {paths: ['${restApiRoot}']},
), function(err) { ), function(err) {
if (err) return done(err); if (err) return done(err);
supertest(app).get('/component').end(function(err, res) { supertest(app).get('/component').end(function(err, res) {
if (err) return done(err); if (err) return done(err);
expect(res.body.paths).to.eql( expect(res.body.paths).to.eql(
[app.get('restApiRoot')] [app.get('restApiRoot')],
); );
done(); done();
}); });
@ -872,7 +871,7 @@ describe('executor', function() {
it('should parse config variables in an object', function(done) { it('should parse config variables in an object', function(done) {
boot.execute(app, simpleComponentConfig( boot.execute(app, simpleComponentConfig(
{info: {path: '${restApiRoot}'}} {info: {path: '${restApiRoot}'}},
), function(err) { ), function(err) {
if (err) return done(err); if (err) return done(err);
@ -888,7 +887,7 @@ describe('executor', function() {
it('should parse config variables in a nested object', function(done) { it('should parse config variables in a nested object', function(done) {
boot.execute(app, simpleComponentConfig( boot.execute(app, simpleComponentConfig(
{nested: {info: {path: '${restApiRoot}'}}} {nested: {info: {path: '${restApiRoot}'}}},
), function(err) { ), function(err) {
if (err) return done(err); if (err) return done(err);
@ -904,7 +903,7 @@ describe('executor', function() {
}); });
it('calls function exported by boot/init.js', function(done) { it('calls function exported by boot/init.js', function(done) {
var file = appdir.writeFileSync('boot/init.js', const file = appdir.writeFileSync('boot/init.js',
'module.exports = function(app) { app.fnCalled = true; };'); 'module.exports = function(app) { app.fnCalled = true; };');
delete app.fnCalled; delete app.fnCalled;
@ -917,7 +916,7 @@ describe('executor', function() {
}); });
it('configures middleware', function(done) { it('configures middleware', function(done) {
var pushNamePath = require.resolve('./helpers/push-name-middleware'); const pushNamePath = require.resolve('./helpers/push-name-middleware');
boot.execute(app, someInstructions({ boot.execute(app, someInstructions({
middleware: { middleware: {
@ -961,7 +960,7 @@ describe('executor', function() {
.get('/') .get('/')
.end(function(err, res) { .end(function(err, res) {
if (err) return done(err); if (err) return done(err);
var names = (res.headers.names || '').split(','); const names = (res.headers.names || '').split(',');
expect(names).to.eql(['initial', 'custom', 'routes']); expect(names).to.eql(['initial', 'custom', 'routes']);
done(); done();
}); });
@ -989,7 +988,7 @@ describe('executor', function() {
.get('/') .get('/')
.end(function(err, res) { .end(function(err, res) {
if (err) return done(err); if (err) return done(err);
var EXPECTED_TEXT = '<!DOCTYPE html>\n<html>\n<head lang="en">\n' + const EXPECTED_TEXT = '<!DOCTYPE html>\n<html>\n<head lang="en">\n' +
' <meta charset="UTF-8">\n <title>simple-app</title>\n' + ' <meta charset="UTF-8">\n <title>simple-app</title>\n' +
'</head>\n<body>\n<h1>simple-app</h1>\n' + '</head>\n<body>\n<h1>simple-app</h1>\n' +
'</body>\n</html>'; '</body>\n</html>';
@ -1031,7 +1030,7 @@ describe('executor', function() {
if (err) return done(err); if (err) return done(err);
expect(Object.keys(require.cache)).to.include( expect(Object.keys(require.cache)).to.include(
appdir.resolve('components/test-component/index.js') appdir.resolve('components/test-component/index.js'),
); );
expect(app.componentOptions).to.eql({option: 'value'}); expect(app.componentOptions).to.eql({option: 'value'});
@ -1052,7 +1051,7 @@ describe('executor', function() {
if (err) return done(err); if (err) return done(err);
expect(Object.keys(require.cache)).to.not.include( expect(Object.keys(require.cache)).to.not.include(
appdir.resolve('components/test-component/index.js') appdir.resolve('components/test-component/index.js'),
); );
done(); done();
}); });
@ -1075,14 +1074,14 @@ describe('executor', function() {
if (err) return done(err); if (err) return done(err);
expect(Object.keys(require.cache)).to.not.include( expect(Object.keys(require.cache)).to.not.include(
appdir.resolve('components/test-component/index.js') appdir.resolve('components/test-component/index.js'),
); );
done(); done();
}); });
}); });
it('configures middleware (that requires `this`)', function(done) { it('configures middleware (that requires `this`)', function(done) {
var passportPath = require.resolve('./fixtures/passport'); const passportPath = require.resolve('./fixtures/passport');
boot.execute(app, someInstructions({ boot.execute(app, someInstructions({
middleware: { middleware: {
@ -1122,7 +1121,7 @@ describe('executor', function() {
}); });
describe('when booting with lazy connect', function() { describe('when booting with lazy connect', function() {
var SAMPLE_INSTRUCTION = someInstructions({ const SAMPLE_INSTRUCTION = someInstructions({
dataSources: { dataSources: {
lazyConnector: { lazyConnector: {
connector: 'testLazyConnect', connector: 'testLazyConnect',
@ -1130,7 +1129,7 @@ describe('executor', function() {
}, },
}, },
}); });
var connectTriggered = true; let connectTriggered = true;
beforeEach(function() { beforeEach(function() {
app.connector('testLazyConnect', { app.connector('testLazyConnect', {
@ -1184,14 +1183,14 @@ describe('executor', function() {
}); });
it('should convert dynamic variable for datasource', function(done) { it('should convert dynamic variable for datasource', function(done) {
var datasource = { const datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
port: '${DYNAMIC_PORT}', port: '${DYNAMIC_PORT}',
}, },
}; };
var bootInstructions = {dataSources: datasource}; const bootInstructions = {dataSources: datasource};
process.env.DYNAMIC_PORT = '10007'; process.env.DYNAMIC_PORT = '10007';
process.env.DYNAMIC_HOST = '123.321.123.132'; process.env.DYNAMIC_HOST = '123.321.123.132';
@ -1204,20 +1203,20 @@ describe('executor', function() {
}); });
it('should resolve dynamic config via app.get()', function(done) { it('should resolve dynamic config via app.get()', function(done) {
var datasource = { const datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
}, },
}; };
var bootInstructions = { const bootInstructions = {
application: {DYNAMIC_HOST: '127.0.0.4'}, application: {DYNAMIC_HOST: '127.0.0.4'},
dataSources: datasource, dataSources: datasource,
}; };
boot.execute(app, someInstructions(bootInstructions), function() { boot.execute(app, someInstructions(bootInstructions), function() {
expect(app.get('DYNAMIC_HOST')).to.equal('127.0.0.4'); expect(app.get('DYNAMIC_HOST')).to.equal('127.0.0.4');
expect(app.datasources.mydb.settings.host).to.equal( expect(app.datasources.mydb.settings.host).to.equal(
'127.0.0.4' '127.0.0.4',
); );
done(); done();
}); });
@ -1225,13 +1224,13 @@ describe('executor', function() {
it('should take ENV precedence over config.json', function(done) { it('should take ENV precedence over config.json', function(done) {
process.env.DYNAMIC_HOST = '127.0.0.2'; process.env.DYNAMIC_HOST = '127.0.0.2';
var datasource = { const datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
}, },
}; };
var bootInstructions = { const bootInstructions = {
application: {DYNAMIC_HOST: '127.0.0.3'}, application: {DYNAMIC_HOST: '127.0.0.3'},
dataSources: datasource, dataSources: datasource,
}; };
@ -1243,13 +1242,13 @@ describe('executor', function() {
}); });
it('empty dynamic conf should resolve as `undefined`', function(done) { it('empty dynamic conf should resolve as `undefined`', function(done) {
var datasource = { const datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
}, },
}; };
var bootInstructions = {dataSources: datasource}; const bootInstructions = {dataSources: datasource};
boot.execute(app, someInstructions(bootInstructions), function() { boot.execute(app, someInstructions(bootInstructions), function() {
expect(app.get('DYNAMIC_HOST')).to.be.undefined(); expect(app.get('DYNAMIC_HOST')).to.be.undefined();
@ -1266,7 +1265,7 @@ function simpleMiddlewareConfig(phase, paths, params) {
paths = undefined; paths = undefined;
} }
var config = { const config = {
phase: phase, phase: phase,
params: params, params: params,
}; };
@ -1315,7 +1314,7 @@ assert.isFunc = function(obj, name) {
}; };
function someInstructions(values) { function someInstructions(values) {
var result = { const result = {
application: values.application || {}, application: values.application || {},
models: values.models || [], models: values.models || [],
dataSources: values.dataSources || {db: {connector: 'memory'}}, dataSources: values.dataSources || {db: {connector: 'memory'}},
@ -1328,7 +1327,7 @@ function someInstructions(values) {
result.env = values.env; result.env = values.env;
if (values.files) { if (values.files) {
for (var k in values.files) for (const k in values.files)
result.files[k] = values.files[k]; result.files[k] = values.files[k];
} }

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var loopback = require('loopback'); const loopback = require('loopback');
var boot = require('../../../'); const boot = require('../../../');
var app = module.exports = loopback(); const app = module.exports = loopback();
boot(app, { boot(app, {
appId: 'browserApp2', appId: 'browserApp2',
appRootDir: __dirname, appRootDir: __dirname,

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var loopback = require('loopback'); const loopback = require('loopback');
var boot = require('../../../'); const boot = require('../../../');
var app = module.exports = loopback(); const app = module.exports = loopback();
boot(app, __dirname); boot(app, __dirname);

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var framework = { const framework = {
initialize: function(passport) { initialize: function(passport) {
return function(req, res, next) { return function(req, res, next) {
req._passport = passport; req._passport = passport;
@ -15,7 +15,7 @@ var framework = {
}, },
}; };
var Passport = function() { const Passport = function() {
this._framework = framework; this._framework = framework;
}; };

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2017. All Rights Reserved. // Copyright IBM Corp. 2017,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var Promise = require('bluebird'); const Promise = require('bluebird');
module.exports = function(app, callback) { module.exports = function(app, callback) {
callback(); callback();

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2017. All Rights Reserved. // Copyright IBM Corp. 2017,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var Promise = require('bluebird'); const Promise = require('bluebird');
process.bootFlags.push('promiseLoaded'); process.bootFlags.push('promiseLoaded');
module.exports = function(app) { module.exports = function(app) {

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2017. All Rights Reserved. // Copyright IBM Corp. 2017,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var Promise = require('bluebird'); const Promise = require('bluebird');
module.exports = function(app) { module.exports = function(app) {
if (process.rejectPromise) { if (process.rejectPromise) {

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2017. All Rights Reserved. // Copyright IBM Corp. 2018,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,3 +1,8 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
module.exports = function(opitions) { module.exports = function(opitions) {

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var path = require('path'); const path = require('path');
var fs = require('fs-extra'); const fs = require('fs-extra');
var extend = require('util')._extend; const extend = require('util')._extend;
var sandbox = require('./sandbox'); const sandbox = require('./sandbox');
var appdir = exports; const appdir = exports;
var PATH = appdir.PATH = null; let PATH = appdir.PATH = null;
appdir.init = function(cb) { appdir.init = function(cb) {
// Node's module loader has a very aggressive caching, therefore // Node's module loader has a very aggressive caching, therefore
@ -20,7 +20,7 @@ appdir.init = function(cb) {
// The code here is used to generate a random string // The code here is used to generate a random string
require('crypto').randomBytes(5, function(err, buf) { require('crypto').randomBytes(5, function(err, buf) {
if (err) return cb(err); if (err) return cb(err);
var randomStr = buf.toString('hex'); const randomStr = buf.toString('hex');
PATH = appdir.PATH = sandbox.resolve(randomStr); PATH = appdir.PATH = sandbox.resolve(randomStr);
cb(null, appdir.PATH); cb(null, appdir.PATH);
}); });
@ -49,7 +49,7 @@ appdir.writeConfigFileSync = function(name, json) {
}; };
appdir.writeFileSync = function(name, content) { appdir.writeFileSync = function(name, content) {
var filePath = this.resolve(name); const filePath = this.resolve(name);
fs.mkdirsSync(path.dirname(filePath)); fs.mkdirsSync(path.dirname(filePath));
fs.writeFileSync(filePath, content, 'utf-8'); fs.writeFileSync(filePath, content, 'utf-8');
return filePath; return filePath;

View File

@ -1,16 +1,17 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var vm = require('vm'); const vm = require('vm');
function createContext() { function createContext() {
var context = { const context = {
// required by browserify // required by browserify
XMLHttpRequest: function() { throw new Error('not implemented'); }, XMLHttpRequest: function() {},
clearTimeout: function() {},
FormData: function() { throw new Error('not implemented'); }, FormData: function() { throw new Error('not implemented'); },
localStorage: { localStorage: {
@ -32,7 +33,7 @@ function createContext() {
DataView: DataView, DataView: DataView,
crypto: { crypto: {
getRandomValues: function(typedArray) { getRandomValues: function(typedArray) {
var randomBuffer = require('crypto').randomBytes(typedArray.length); const randomBuffer = require('crypto').randomBytes(typedArray.length);
// This implementation is not secure: we take random 8bit values // This implementation is not secure: we take random 8bit values
// and assign them to 8/16/32bit values, leaving high-order bits // and assign them to 8/16/32bit values, leaving high-order bits
// filled with zeroes. // filled with zeroes.
@ -72,9 +73,9 @@ function createContext() {
exports.createContext = createContext; exports.createContext = createContext;
function printContextLogs(context) { function printContextLogs(context) {
var k, ix; // see https://github.com/eslint/eslint/issues/5744 let k, ix; // see https://github.com/eslint/eslint/issues/5744
for (k in context.console._logs) { for (k in context.console._logs) {
var items = context.console._logs[k]; const items = context.console._logs[k];
for (ix in items) { for (ix in items) {
console[k].apply(console, items[ix]); console[k].apply(console, items[ix]);
} }

View File

@ -1,16 +1,16 @@
// Copyright IBM Corp. 2015. All Rights Reserved. // Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var fs = require('fs'); const fs = require('fs');
var sandbox = require('./sandbox'); const sandbox = require('./sandbox');
function exportToSandbox(b, fileName, callback) { function exportToSandbox(b, fileName, callback) {
var bundlePath = sandbox.resolve(fileName); const bundlePath = sandbox.resolve(fileName);
var out = fs.createWriteStream(bundlePath); const out = fs.createWriteStream(bundlePath);
b.bundle().pipe(out); b.bundle().pipe(out);
out.on('error', function(err) { out.on('error', function(err) {
@ -21,3 +21,16 @@ function exportToSandbox(b, fileName, callback) {
}); });
} }
exports.exportToSandbox = exportToSandbox; exports.exportToSandbox = exportToSandbox;
exports.packageFilter = function packageFilter(pkg, dir) {
// async@3 (used e.g. by loopback-connector) is specifying custom
// browserify config, in particular it wants to apply transformation
// `babelify`. We don't have `babelify` installed because we are
// testing using latest Chrome and thus don't need any transpilation.
// Let's remove the browserify config from the package and force
// browserify to use our config instead.
if (pkg.name === 'async') {
delete pkg.browserify;
}
return pkg;
};

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2014. All Rights Reserved. // Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var fs = require('fs-extra'); const fs = require('fs-extra');
var path = require('path'); const path = require('path');
var sandbox = exports; const sandbox = exports;
sandbox.PATH = path.join(__dirname, '..', 'sandbox'); sandbox.PATH = path.join(__dirname, '..', 'sandbox');
sandbox.reset = function() { sandbox.reset = function() {
@ -17,7 +17,7 @@ sandbox.reset = function() {
}; };
sandbox.resolve = function() { sandbox.resolve = function() {
var args = Array.prototype.slice.apply(arguments); const args = Array.prototype.slice.apply(arguments);
args.unshift(sandbox.PATH); args.unshift(sandbox.PATH);
return path.resolve.apply(path.resolve, args); return path.resolve.apply(path.resolve, args);
}; };

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2014,2016. All Rights Reserved. // Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Node module: loopback-boot // Node module: loopback-boot
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var utils = require('../lib/utils'); const utils = require('../lib/utils');
var expect = require('chai').expect; const expect = require('chai').expect;
var sandbox = require('./helpers/sandbox'); const sandbox = require('./helpers/sandbox');
var appdir = require('./helpers/appdir'); const appdir = require('./helpers/appdir');
describe('utils', function() { describe('utils', function() {
beforeEach(sandbox.reset); beforeEach(sandbox.reset);
@ -17,13 +17,13 @@ describe('utils', function() {
}); });
describe('fileExistsSync', function() { describe('fileExistsSync', function() {
it('returns false when a file does not exist', function() { it('returns false when a file does not exist', function() {
var doesNotExist = sandbox.resolve('does-not-exist.json'); const doesNotExist = sandbox.resolve('does-not-exist.json');
expect(utils.fileExistsSync(doesNotExist)) expect(utils.fileExistsSync(doesNotExist))
.to.equal(false); .to.equal(false);
}); });
it('returns true when a file does exist', function() { it('returns true when a file does exist', function() {
var doesExist = appdir.writeConfigFileSync('does-exist.json', { const doesExist = appdir.writeConfigFileSync('does-exist.json', {
exists: true, exists: true,
}); });
expect(utils.fileExistsSync(doesExist)) expect(utils.fileExistsSync(doesExist))