Compare commits

..

No commits in common. "master" and "v3.2.1" have entirely different histories.

61 changed files with 1063 additions and 1216 deletions

37
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,37 @@
<!--
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
-->

View File

@ -1,50 +0,0 @@
---
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

@ -1,25 +0,0 @@
---
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.

View File

@ -1,27 +0,0 @@
---
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/
-->

View File

@ -1,11 +0,0 @@
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,18 +1,25 @@
### Description
#### Related issues
<!-- <!--
Please provide a high-level description of the changes made by your pull request. Please use the following link syntaxes:
Include references to all related GitHub issues and other pull requests, for example: - connect to #49 (to reference issues in the current repository)
- connect to strongloop/loopback#49 (to reference issues in another repository)
Fixes #123
Implements #254
See also #23
--> -->
## Checklist - connect to <link_to_referenced_issue>
👉 [Read and sign the CLA (Contributor License Agreement)](https://cla.strongloop.com/agreements/strongloop/loopback-boot) 👈 ### Checklist
<!--
- 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 guide](https://loopback.io/doc/en/contrib/style-guide-es6.html) - [ ] Code conforms with the [style
- [ ] Commit messages are following our [guidelines](https://loopback.io/doc/en/contrib/git-commit-messages.html) guide](http://loopback.io/doc/en/contrib/style-guide.html)

24
.github/stale.yml vendored
View File

@ -1,24 +0,0 @@
# 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,6 +1,7 @@
sudo: false sudo: false
language: node_js language: node_js
node_js: node_js:
- "6"
- "8" - "8"
- "10" - "10"

View File

@ -1,17 +1,3 @@
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,13 +1,12 @@
# LoopBack Boot # LoopBack Boot
**⚠️ LoopBack 3 has reached end of life. We are no longer accepting pull requests or providing **This module is in Active LTS mode, new features are no longer accepted.**
support for community users. The only exception is fixes for critical bugs and security <br/>(See [Module Long Term Support Policy](#module-long-term-support-policy)
vulnerabilities provided as part of support for IBM API Connect customers. (See below.)
[Module Long Term Support Policy](#module-long-term-support-policy) below.)**
We urge all LoopBack 3 users to migrate their applications to LoopBack 4 as LoopBack 3 users looking for new features are encouraged to upgrade
soon as possible. Refer to our to LoopBack 4. Refer to
[Migration Guide](https://loopback.io/doc/en/lb4/migration-overview.html) [loopback-next#1849](https://github.com/strongloop/loopback-next/issues/1849)
for more information on how to upgrade. for more information on how to upgrade.
## Overview ## Overview
@ -64,8 +63,8 @@ with the following End Of Life (EOL) dates:
| Version | Status | Published | EOL | | Version | Status | Published | EOL |
| ------- | --------------- | --------- | -------- | | ------- | --------------- | --------- | -------- |
| 3.x | End-of-Life | May 2017 | Dec 2020 | | 3.x | Active LTS | May 2017 | Dec 2019 |
| 2.x | End-of-Life | Jul 2014 | Apr 2019 | | 2.x | Maintenance LTS | 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const Bootstrapper = require('./lib/bootstrapper'); var Bootstrapper = require('./lib/bootstrapper');
/** /**
* The browser version of `bootLoopBackApp`. * The browser version of `bootLoopBackApp`.
@ -26,18 +26,18 @@ const 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.
let moduleName = 'loopback-boot#instructions'; var moduleName = 'loopback-boot#instructions';
const appId = options && typeof options === 'object' && options.appId; var 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
const instructions = require(moduleName); var instructions = require(moduleName);
const bootstrapper = new Bootstrapper(options); var bootstrapper = new Bootstrapper(options);
bootstrapper.phases = ['starting', 'start', 'started']; bootstrapper.phases = ['starting', 'start', 'started'];
const context = { var context = {
app: app, app: app,
instructions: instructions, instructions: instructions,
}; };

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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
const g = require('./lib/globalize'); var g = require('./lib/globalize');
const PluginBase = require('./lib/plugin-base'); var PluginBase = require('./lib/plugin-base');
const Bootstrapper = require('./lib/bootstrapper'); var Bootstrapper = require('./lib/bootstrapper');
const addInstructionsToBrowserify = require('./lib/bundler'); var 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');
const bootstrapper = new Bootstrapper(options); var bootstrapper = new Bootstrapper(options);
const context = { var 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) {
const bootstrapper = new Bootstrapper(options); var bootstrapper = new Bootstrapper(options);
bootstrapper.phases = ['load', 'compile']; bootstrapper.phases = ['load', 'compile'];
const context = {}; var 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) {
const bootstrapper = new Bootstrapper( var bootstrapper = new Bootstrapper(
{phases: ['starting', 'start', 'started']}, {phases: ['starting', 'start', 'started']}
); );
const context = { var context = {
app: app, app: app,
instructions: instructions, instructions: instructions,
}; };

64
lib/bootstrapper.js vendored
View File

@ -1,25 +1,25 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const _ = require('lodash'); var _ = require('lodash');
const assert = require('assert'); var assert = require('assert');
const async = require('async'); var async = require('async');
const utils = require('./utils'); var utils = require('./utils');
const path = require('path'); var path = require('path');
const pluginLoader = require('./plugin-loader'); var pluginLoader = require('./plugin-loader');
const debug = require('debug')('loopback:boot:bootstrapper'); var debug = require('debug')('loopback:boot:bootstrapper');
const Promise = require('bluebird'); var Promise = require('bluebird');
const arrayToObject = require('./utils').arrayToObject; var arrayToObject = require('./utils').arrayToObject;
module.exports = Bootstrapper; module.exports = Bootstrapper;
function createPromiseCallback() { function createPromiseCallback() {
let cb; var cb;
const promise = new Promise(function(resolve, reject) { var 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;
} }
const builtinPlugins = [ var builtinPlugins = [
'application', 'datasource', 'model', 'mixin', 'application', 'datasource', 'model', 'mixin',
'middleware', 'component', 'boot-script', 'swagger', 'middleware', 'component', 'boot-script', 'swagger',
]; ];
const builtinPhases = [ var builtinPhases = [
'load', 'compile', 'starting', 'start', 'started', 'load', 'compile', 'starting', 'start', 'started',
]; ];
function loadAndRegisterPlugins(bootstrapper, options) { function loadAndRegisterPlugins(bootstrapper, options) {
const loader = pluginLoader(options); var loader = pluginLoader(options);
const loaderContext = {}; var loaderContext = {};
loader.load(loaderContext); loader.load(loaderContext);
loader.compile(loaderContext); loader.compile(loaderContext);
for (const i in loaderContext.instructions.pluginScripts) { for (var 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);
const appRootDir = options.appRootDir = options.appRootDir || process.cwd(); var appRootDir = options.appRootDir = options.appRootDir || process.cwd();
const env = options.env || process.env.NODE_ENV || 'development'; var env = options.env || process.env.NODE_ENV || 'development';
const scriptExtensions = options.scriptExtensions ? var scriptExtensions = options.scriptExtensions ?
arrayToObject(options.scriptExtensions) : arrayToObject(options.scriptExtensions) :
require.extensions; require.extensions;
const appConfigRootDir = options.appConfigRootDir || appRootDir; var 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);
const self = this; var self = this;
self.builtinPlugins.forEach(function(p) { self.builtinPlugins.forEach(function(p) {
const factory = require('./plugins/' + p); var 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) {
const plugin = { var 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;
const name = p.path.substring(path.length); var 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) {
let result; var 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();
} }
const options = this.options; var options = this.options;
const appRootDir = options.appRootDir = options.appRootDir || process.cwd(); var appRootDir = options.appRootDir = options.appRootDir || process.cwd();
const env = options.env || process.env.NODE_ENV || 'development'; var env = options.env || process.env.NODE_ENV || 'development';
const appConfigRootDir = options.appConfigRootDir || appRootDir; var appConfigRootDir = options.appConfigRootDir || appRootDir;
options.rootDir = appConfigRootDir; options.rootDir = appConfigRootDir;
options.env = env; options.env = env;
context = context || {}; context = context || {};
const phases = context.phases || this.phases; var 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;
} }
const bootPlugins = this.getExtensions('/boot'); var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const fs = require('fs'); var fs = require('fs');
const path = require('path'); var path = require('path');
const commondir = require('commondir'); var commondir = require('commondir');
const cloneDeep = require('lodash').cloneDeep; var cloneDeep = require('lodash').cloneDeep;
const g = require('./globalize'); var 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) {
const dir = path.join(__dirname, './plugins'); var dir = path.join(__dirname, './plugins');
const files = fs.readdirSync(dir); var 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) {
const list = context.instructions.bootScripts; var list = context.instructions.bootScripts;
addScriptsToBundle('boot', list, bundler); addScriptsToBundle('boot', list, bundler);
} }
function bundlePluginScripts(context, bundler) { function bundlePluginScripts(context, bundler) {
const list = context.instructions.pluginScripts; var 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) {
const files = context.instructions[type] var 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; });
const instructionToFileMapping = context.instructions[type] var 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,16 +77,15 @@ function bundleSourceFiles(context, type, bundler) {
function addScriptsToBundle(name, list, bundler) { function addScriptsToBundle(name, list, bundler) {
if (!list.length) return; if (!list.length) return;
const root = commondir(list.map(path.dirname)); var root = commondir(list.map(path.dirname));
for (const ix in list) { for (var ix in list) {
const filepath = list[ix]; var 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.
const fileid = var fileid = 'loopback-boot#' + name + '#' + path.relative(root, filepath);
'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});
@ -98,19 +97,19 @@ function addScriptsToBundle(name, list, bundler) {
} }
function bundleInstructions(context, bundler) { function bundleInstructions(context, bundler) {
const instructions = cloneDeep(context.instructions); var instructions = cloneDeep(context.instructions);
const hasMiddleware = instructions.middleware.phases.length || var 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;
const instructionsString = JSON.stringify(instructions, null, 2); var 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
@ -120,7 +119,7 @@ function bundleInstructions(context, bundler) {
b.require(instructionsStream, { expose: 'loopback-boot#instructions' }); b.require(instructionsStream, { expose: 'loopback-boot#instructions' });
*/ */
let instructionId = 'instructions'; var 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.
@ -129,10 +128,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
const instructionsFile = path.resolve(__dirname, var instructionsFile = path.resolve(__dirname,
'..', 'generated-' + instructionId + '.json'); '..', 'generated-' + instructionId + '.json');
fs.writeFileSync(instructionsFile, instructionsString, 'utf-8'); fs.writeFileSync(instructionsFile, instructionsString, 'utf-8');
const moduleName = 'loopback-boot#' + instructionId; var moduleName = 'loopback-boot#' + instructionId;
bundler.require(instructionsFile, {expose: moduleName}); bundler.require(instructionsFile, {expose: moduleName});
} }

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const path = require('path'); var path = require('path');
const SG = require('strong-globalize'); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const fs = require('fs'); var fs = require('fs');
const path = require('path'); var path = require('path');
const debug = require('debug')('loopback:boot:plugin'); var debug = require('debug')('loopback:boot:plugin');
const assert = require('assert'); var assert = require('assert');
const _ = require('lodash'); var _ = require('lodash');
const util = require('./utils'); var util = require('./utils');
const g = require('./globalize'); var 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) {
const rootDir = this.getRootDir() || this.options.rootDir; var rootDir = this.getRootDir() || this.options.rootDir;
const env = this.options.env; var 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);
let config = {}; var 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) {
const files = this.findConfigFiles(rootDir, env, name); var 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);
}); });
} }
const configs = this._loadConfigFiles(files); var configs = this._loadConfigFiles(files);
const merged = this._mergeConfigurations(configs); var 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) {
const master = ifExists(name + '.json'); var 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 [];
const candidates = [ var 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) {
const filePath = path.resolve(rootDir, fileName); var filePath = path.resolve(rootDir, fileName);
return util.fileExistsSync(filePath) ? filePath : undefined; return util.fileExistsSync(filePath) ? filePath : undefined;
} }
function ifExistsWithAnyExt(fileName) { function ifExistsWithAnyExt(fileName) {
const extensions = exts || ['js', 'json']; var extensions = exts || ['js', 'json'];
let file; var file;
for (let i = 0, n = extensions.length; i < n; i++) { for (var 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) {
let config = require(f); var 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) {
const result = configObjects.shift() || {}; var result = configObjects.shift() || {};
while (configObjects.length) { while (configObjects.length) {
const next = configObjects.shift(); var 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 (const key in config) { for (var key in config) {
const fullKey = keyPrefix ? keyPrefix + '.' + key : key; var fullKey = keyPrefix ? keyPrefix + '.' + key : key;
const err = this._mergeSingleItemOrProperty(target, config, key, fullKey); var 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';
const result = [].concat(arr1); var result = [].concat(arr1);
for (let i = 0, n = arr2.length; i < n; i++) { for (var i = 0, n = arr2.length; i < n; i++) {
const item = arr2[i]; var item = arr2[i];
let found = false; var found = false;
if (item[key]) { if (item[key]) {
for (let j = 0, k = result.length; j < k; j++) { for (var 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) {
const origValue = target[key]; var origValue = target[key];
const newValue = config[key]; var 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 (let ix = 0; ix < target.length; ix++) { for (var ix = 0; ix < target.length; ix++) {
const fullKey = keyPrefix + '[' + ix + ']'; var fullKey = keyPrefix + '[' + ix + ']';
const err = this._mergeSingleItemOrProperty(target, config, ix, fullKey); var 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) {
let instructions; var instructions;
if (typeof this.buildInstructions === 'function') { if (typeof this.buildInstructions === 'function') {
const rootDir = this.options.rootDir; var rootDir = this.options.rootDir;
const config = context.configurations[this.name] || {}; var 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;
}; };
const DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/; var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/;
function getConfigVariable(app, param, useEnvVars) { function getConfigVariable(app, param, useEnvVars) {
let configVariable = param; var configVariable = param;
const match = configVariable.match(DYNAMIC_CONFIG_PARAM); var match = configVariable.match(DYNAMIC_CONFIG_PARAM);
if (match) { if (match) {
const varName = match[1]; var 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);
const appValue = app.get(varName); var 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) {
const app = context.app; var app = context.app;
const useEnvVars = opts && opts.useEnvVars; var 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
const interpolated = {}; var interpolated = {};
Object.keys(config).forEach(function(configKey) { Object.keys(config).forEach(function(configKey) {
const value = config[configKey]; var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const utils = require('./utils'); var utils = require('./utils');
const path = require('path'); var path = require('path');
const async = require('async'); var async = require('async');
const debug = require('debug')('loopback:boot:plugin-loader'); var debug = require('debug')('loopback:boot:plugin-loader');
const PluginBase = require('./plugin-base'); var PluginBase = require('./plugin-base');
const _ = require('lodash'); var _ = 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) {
const options = this.options; var options = this.options;
const appRootDir = options.rootDir; var appRootDir = options.rootDir;
// require directories // require directories
let pluginDirs = options.pluginDirs || []; // precedence var 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);
let pluginScripts = options.pluginScripts || []; var 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)
); );
const envdir = dir + '/' + options.env; var 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) {
const pluginScripts = context.configurations.pluginScripts; var pluginScripts = context.configurations.pluginScripts;
context.instructions = context.instructions || {}; context.instructions = context.instructions || {};
const plugins = context.instructions.pluginScripts = {}; var plugins = context.instructions.pluginScripts = {};
const self = this; var self = this;
pluginScripts.forEach(function(ps) { pluginScripts.forEach(function(ps) {
debug('Loading %s', ps); debug('Loading %s', ps);
const factory = require(ps); var factory = require(ps);
const handler = factory(self.options); var handler = factory(self.options);
const name = handler.name || path.basename(ps, '.js'); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const assert = require('assert'); var assert = require('assert');
const semver = require('semver'); var semver = require('semver');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const g = require('../globalize'); var 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) {
const RANGE = '2.x || 3.x'; var RANGE = '2.x || 3.x';
const loopback = app.loopback; var 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
const version = (loopback.version || '1.0.0').replace(/-.*$/, ''); var version = (loopback.version || '1.0.0').replace(/-.*$/, '');
if (!semver.satisfies(version, RANGE)) { if (!semver.satisfies(version, RANGE)) {
const msg = g.f( var 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
const host = var 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
const port = find([ var 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) {
const portType = typeof port; var 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) {
const restApiRoot = var 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 (const configKey in appConfig) { for (var configKey in appConfig) {
const cur = app.get(configKey); var 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) {
const app = context.app; var app = context.app;
assertLoopBackVersion(app); assertLoopBackVersion(app);
const appConfig = context.instructions.application; var 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) {
const app = context.app; var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const utils = require('../utils'); var utils = require('../utils');
const path = require('path'); var path = require('path');
const async = require('async'); var async = require('async');
const debug = require('debug')('loopback:boot:script'); var debug = require('debug')('loopback:boot:script');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const _ = require('lodash'); var _ = require('lodash');
const g = require('../globalize'); var 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) {
const options = this.options; var options = this.options;
const appRootDir = options.rootDir; var appRootDir = options.rootDir;
// require directories // require directories
let bootDirs = options.bootDirs || []; // precedence var 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);
let bootScripts = options.bootScripts || []; var 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)
); );
const envdir = dir + '/' + options.env; var 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) {
const app = context.app; var app = context.app;
const instructions = context.instructions[this.name]; var 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 || [];
const functions = []; var functions = [];
list.forEach(function(filepath) { list.forEach(function(filepath) {
debug('Requiring script %s', filepath); debug('Requiring script %s', filepath);
try { try {
let exports = require(filepath); var 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);
let cb = function(err) { var 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 {
const result = f.func(app, cb); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const debug = require('debug')('loopback:boot:component'); var debug = require('debug')('loopback:boot:component');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const utils = require('../utils'); var utils = require('../utils');
const resolveAppScriptPath = utils.resolveAppScriptPath; var 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) {
const app = context.app; var app = context.app;
const self = this; var 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);
const configFn = require(data.sourceFile); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const utils = require('../utils'); var utils = require('../utils');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const debug = require('debug')('loopback:boot:datasource'); var 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) {
const app = context.app; var app = context.app;
const self = this; var self = this;
const lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES; var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const assert = require('assert'); var assert = require('assert');
const path = require('path'); var path = require('path');
const _ = require('lodash'); var _ = require('lodash');
const cloneDeepWith = _.cloneDeepWith; var cloneDeepWith = _.cloneDeepWith;
const cloneDeep = _.cloneDeep; var cloneDeep = _.cloneDeep;
const debug = require('debug')('loopback:boot:middleware'); var debug = require('debug')('loopback:boot:middleware');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const utils = require('../utils'); var utils = require('../utils');
const g = require('../globalize'); var g = require('../globalize');
const resolveAppScriptPath = utils.resolveAppScriptPath; var 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) {
let err, phase; var 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) {
let err, mw; var err, mw;
for (mw in config) { for (mw in config) {
if (mw in target) { if (mw in target) {
const targetMiddleware = target[mw]; var targetMiddleware = target[mw];
const configMiddleware = config[mw]; var 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) {
const phasesNames = Object.keys(config); var phasesNames = Object.keys(config);
const middlewareList = []; var middlewareList = [];
phasesNames.forEach(function(phase) { phasesNames.forEach(function(phase) {
const phaseConfig = config[phase]; var phaseConfig = config[phase];
Object.keys(phaseConfig).forEach(function(middleware) { Object.keys(phaseConfig).forEach(function(middleware) {
let allConfigs = phaseConfig[middleware]; var allConfigs = phaseConfig[middleware];
if (!Array.isArray(allConfigs)) if (!Array.isArray(allConfigs))
allConfigs = [allConfigs]; allConfigs = [allConfigs];
allConfigs.forEach(function(config) { allConfigs.forEach(function(config) {
const resolved = resolveMiddlewarePath(rootDir, middleware, config); var 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);
} }
const middlewareConfig = cloneDeep(config); var 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
); );
} }
const item = { var item = {
sourceFile: resolved.sourceFile, sourceFile: resolved.sourceFile,
config: middlewareConfig, config: middlewareConfig,
}; };
@ -126,7 +126,7 @@ Middleware.prototype.buildInstructions = function(context, rootDir, config) {
}); });
}); });
const flattenedPhaseNames = phasesNames var 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) {
const resolved = { var resolved = {
optional: !!config.optional, optional: !!config.optional,
}; };
const segments = middleware.split('#'); var segments = middleware.split('#');
let pathName = segments[0]; var pathName = segments[0];
const fragment = segments[1]; var fragment = segments[1];
const middlewarePath = pathName; var middlewarePath = pathName;
const opts = { var 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);
} }
const resolveOpts = _.extend(opts, { var 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,
}); });
const sourceFile = resolveAppScriptPath(rootDir, middlewarePath, resolveOpts); var 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
const m = require(sourceFile); var 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
*/ */
const candidates = [ var 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
]; ];
let err, ix; var 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 `$!../`
const MIDDLEWARE_PATH_PARAM_REGEX = /^\$!(\.\/|\.\.\/)/; var 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) {
const self = this; var self = this;
const app = context.app; var app = context.app;
const instructions = context.instructions.middleware; var 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
const phases = instructions.phases || []; var phases = instructions.phases || [];
assert(Array.isArray(phases), assert(Array.isArray(phases),
'Middleware phases must be an array'); 'Middleware phases must be an array');
const middleware = instructions.middleware; var 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) : '');
let factory = require(data.sourceFile); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const fs = require('fs'); var fs = require('fs');
const path = require('path'); var path = require('path');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const _ = require('lodash'); var _ = require('lodash');
const debug = require('debug')('loopback:boot:mixin'); var debug = require('debug')('loopback:boot:mixin');
const utils = require('../utils'); var utils = require('../utils');
const g = require('../globalize'); var g = require('../globalize');
const tryResolveAppPath = utils.tryResolveAppPath; var tryResolveAppPath = utils.tryResolveAppPath;
const getExcludedExtensions = utils.getExcludedExtensions; var getExcludedExtensions = utils.getExcludedExtensions;
const findScripts = utils.findScripts; var findScripts = utils.findScripts;
const FILE_EXTENSION_JSON = utils.FILE_EXTENSION_JSON; var 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) {
const modelsMeta = context.configurations.mixins._meta || {}; var modelsMeta = context.configurations.mixins._meta || {};
const modelInstructions = context.instructions.models; var modelInstructions = context.instructions.models;
const mixinSources = this.options.mixinSources || modelsMeta.mixins || var mixinSources = this.options.mixinSources || modelsMeta.mixins ||
['./mixins']; ['./mixins'];
const scriptExtensions = this.options.scriptExtensions || require.extensions; var scriptExtensions = this.options.scriptExtensions || require.extensions;
const mixinInstructions = buildAllMixinInstructions( var 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`
let sourceFiles = options.mixins || []; var sourceFiles = options.mixins || [];
const mixinDirs = options.mixinDirs || []; var mixinDirs = options.mixinDirs || [];
const instructionsFromMixins = loadMixins(sourceFiles, options.normalization); var 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;
const instructionsFromMixinDirs = loadMixins(sourceFiles, var 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;
let instructionsFromMixinSources = loadMixins(sourceFiles, var 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
let modelMixins = fetchMixinNamesUsedInModelInstructions(modelInstructions); var 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
); );
const mixins = _.assign( var mixins = _.assign(
instructionsFromMixins, instructionsFromMixins,
instructionsFromMixinDirs, instructionsFromMixinDirs,
instructionsFromMixinSources, instructionsFromMixinSources
); );
return _.values(mixins); return _.values(mixins);
} }
function findMixinDefinitions(appRootDir, sourceDirs, scriptExtensions) { function findMixinDefinitions(appRootDir, sourceDirs, scriptExtensions) {
let files = []; var files = [];
sourceDirs.forEach(function(dir) { sourceDirs.forEach(function(dir) {
const path = tryResolveAppPath(appRootDir, dir); var 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) {
const mixinInstructions = {}; var mixinInstructions = {};
sourceFiles.forEach(function(filepath) { sourceFiles.forEach(function(filepath) {
const dir = path.dirname(filepath); var dir = path.dirname(filepath);
const ext = path.extname(filepath); var ext = path.extname(filepath);
let name = path.basename(filepath, ext); var name = path.basename(filepath, ext);
const metafile = path.join(dir, name + FILE_EXTENSION_JSON); var metafile = path.join(dir, name + FILE_EXTENSION_JSON);
name = normalizeMixinName(name, normalization); name = normalizeMixinName(name, normalization);
const meta = {}; var 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) {
const instructionKeys = Object.keys(instructions); var instructionKeys = Object.keys(instructions);
includeMixins = _.intersection(instructionKeys, includeMixins); includeMixins = _.intersection(instructionKeys, includeMixins);
const filteredInstructions = {}; var 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);
} }
const err = new Error(g.f('Invalid normalization format - "%s"', var 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) {
const app = context.app; var app = context.app;
const instructions = context.instructions.mixins; var instructions = context.instructions.mixins;
const modelBuilder = (app.registry || app.loopback).modelBuilder; var modelBuilder = (app.registry || app.loopback).modelBuilder;
const BaseClass = app.loopback.Model; var BaseClass = app.loopback.Model;
const mixins = instructions || []; var 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);
const mixin = require(obj.sourceFile); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const assert = require('assert'); var assert = require('assert');
const util = require('util'); var util = require('util');
const PluginBase = require('../plugin-base'); var PluginBase = require('../plugin-base');
const path = require('path'); var path = require('path');
const debug = require('debug')('loopback:boot:model'); var debug = require('debug')('loopback:boot:model');
const _ = require('lodash'); var _ = require('lodash');
const toposort = require('toposort'); var toposort = require('toposort');
const utils = require('../utils'); var utils = require('../utils');
const tryReadDir = utils.tryReadDir; var tryReadDir = utils.tryReadDir;
const assertIsValidConfig = utils.assertIsValidConfig; var assertIsValidConfig = utils.assertIsValidConfig;
const tryResolveAppPath = utils.tryResolveAppPath; var tryResolveAppPath = utils.tryResolveAppPath;
const fixFileExtension = utils.fixFileExtension; var fixFileExtension = utils.fixFileExtension;
const g = require('../globalize'); var g = require('../globalize');
module.exports = function(options) { module.exports = function(options) {
return new Model(options); return new Model(options);
@ -35,42 +35,39 @@ Model.prototype.getRootDir = function() {
}; };
Model.prototype.load = function(context) { Model.prototype.load = function(context) {
const config = PluginBase.prototype.load.apply(this, arguments); var 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) {
const modelsMeta = modelsConfig._meta || {}; var modelsMeta = modelsConfig._meta || {};
delete modelsConfig._meta; delete modelsConfig._meta;
context.configurations.mixins._meta = modelsMeta; context.configurations.mixins._meta = modelsMeta;
const modelSources = this.options.modelSources || modelsMeta.sources || var modelSources = this.options.modelSources || modelsMeta.sources ||
['./models']; ['./models'];
const modelInstructions = buildAllModelInstructions( var 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) {
let registry = verifyModelDefinitions(rootDir, modelDefinitions, var registry = verifyModelDefinitions(rootDir, modelDefinitions,
scriptExtensions); scriptExtensions);
if (!registry) { if (!registry) {
registry = findModelDefinitions(rootDir, sources, scriptExtensions); registry = findModelDefinitions(rootDir, sources, scriptExtensions);
} }
const modelNamesToBuild = addAllBaseModels( var modelNamesToBuild = addAllBaseModels(registry, Object.keys(modelsConfig));
registry,
Object.keys(modelsConfig),
);
const instructions = modelNamesToBuild var instructions = modelNamesToBuild
.map(function createModelInstructions(name) { .map(function createModelInstructions(name) {
const config = modelsConfig[name]; var config = modelsConfig[name];
const definition = registry[name] || {}; var 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);
@ -87,20 +84,20 @@ function buildAllModelInstructions(rootDir, modelsConfig, sources,
} }
function addAllBaseModels(registry, modelNames) { function addAllBaseModels(registry, modelNames) {
const result = []; var result = [];
const visited = {}; var visited = {};
while (modelNames.length) { while (modelNames.length) {
const name = modelNames.shift(); var name = modelNames.shift();
if (visited[name]) continue; if (visited[name]) continue;
visited[name] = true; visited[name] = true;
result.push(name); result.push(name);
const definition = registry[name] && registry[name].definition; var definition = registry[name] && registry[name].definition;
if (!definition) continue; if (!definition) continue;
const base = getBaseModelName(definition); var base = getBaseModelName(definition);
// ignore built-in models like User // ignore built-in models like User
if (!registry[base]) continue; if (!registry[base]) continue;
@ -121,14 +118,14 @@ function getBaseModelName(modelDefinition) {
function sortByInheritance(instructions) { function sortByInheritance(instructions) {
// create edges Base name -> Model name // create edges Base name -> Model name
const edges = instructions var edges = instructions
.map(function(inst) { .map(function(inst) {
return [getBaseModelName(inst.definition), inst.name]; return [getBaseModelName(inst.definition), inst.name];
}); });
const sortedNames = toposort(edges); var sortedNames = toposort(edges);
const instructionsByModelName = {}; var instructionsByModelName = {};
instructions.forEach(function(inst) { instructions.forEach(function(inst) {
instructionsByModelName[inst.name] = inst; instructionsByModelName[inst.name] = inst;
}); });
@ -149,14 +146,14 @@ function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
return undefined; return undefined;
} }
const registry = {}; var registry = {};
modelDefinitions.forEach(function(definition, idx) { modelDefinitions.forEach(function(definition, idx) {
if (definition.sourceFile) { if (definition.sourceFile) {
const fullPath = path.resolve(rootDir, definition.sourceFile); var 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) {
@ -171,7 +168,7 @@ function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
path.relative(rootDir, definition.sourceFile) : path.relative(rootDir, definition.sourceFile) :
'(no source file)'); '(no source file)');
const modelName = definition.definition.name; var 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)',
@ -185,26 +182,26 @@ function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
} }
function findModelDefinitions(rootDir, sources, scriptExtensions) { function findModelDefinitions(rootDir, sources, scriptExtensions) {
const registry = {}; var registry = {};
sources.forEach(function(src) { sources.forEach(function(src) {
const srcDir = tryResolveAppPath(rootDir, src, {strict: false}); var 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;
} }
const files = tryReadDir(srcDir); var 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) {
const fullPath = path.resolve(srcDir, f); var fullPath = path.resolve(srcDir, f);
const entry = loadModelDefinition(rootDir, fullPath, files, var entry = loadModelDefinition(rootDir, fullPath, files,
scriptExtensions); scriptExtensions);
const modelName = entry.definition.name; var 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));
@ -218,12 +215,12 @@ function findModelDefinitions(rootDir, sources, scriptExtensions) {
} }
function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) { function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) {
const definition = require(jsonFile); var definition = require(jsonFile);
const basename = path.basename(jsonFile, path.extname(jsonFile)); var 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`
const sourceFile = fixFileExtension(jsonFile, allFiles, scriptExtensions); var 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);
@ -241,26 +238,26 @@ function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) {
function assertIsValidModelConfig(config) { function assertIsValidModelConfig(config) {
assertIsValidConfig('model', config); assertIsValidConfig('model', config);
for (const name in config) { for (var name in config) {
const entry = config[name]; var entry = config[name];
const options = entry.options || {}; var options = entry.options || {};
const unsupported = entry.properties || var 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
const LOOPBACK_MODEL_REGEXP = new RegExp( var 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) {
@ -268,19 +265,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`
const srcFile = data.sourceFile; var 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) {
const app = context.app; var app = context.app;
const instructions = context.instructions[this.name]; var instructions = context.instructions[this.name];
const registry = app.registry || app.loopback; var registry = app.registry || app.loopback;
instructions.forEach(function(data) { instructions.forEach(function(data) {
const name = data.name; var name = data.name;
let model; var model;
if (!data.definition) { if (!data.definition) {
model = registry.getModel(name); model = registry.getModel(name);
@ -297,7 +294,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);
const code = require(data.sourceFile); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const util = require('util'); var util = require('util');
const PluginBase = require('../plugin-base'); var 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) {
const app = context.app; var app = context.app;
const appConfig = context.instructions.application; var appConfig = context.instructions.application;
// disable token requirement for swagger, if available // disable token requirement for swagger, if available
const swagger = app.remotes().exports.swagger; var swagger = app.remotes().exports.swagger;
if (!swagger) return; if (!swagger) return;
const requireTokenForSwagger = appConfig.swagger && var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const debug = require('debug')('loopback:boot'); var debug = require('debug')('loopback:boot');
const path = require('path'); var path = require('path');
const Module = require('module'); var Module = require('module');
const fs = require('fs'); var fs = require('fs');
const assert = require('assert'); var assert = require('assert');
const _ = require('lodash'); var _ = require('lodash');
const g = require('./globalize'); var 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;
const FILE_EXTENSION_JSON = exports.FILE_EXTENSION_JSON = '.json'; var 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 @@ const 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');
const files = tryReadDir(dir); var 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) {
} }
}); });
const results = []; var 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;
} }
const filepath = path.resolve(path.join(dir, filename)); var filepath = path.resolve(path.join(dir, filename));
const stats = fs.statSync(filepath); var 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,13 +87,9 @@ function tryReadDir() {
} }
function resolveRelativePaths(relativePaths, appRootDir) { function resolveRelativePaths(relativePaths, appRootDir) {
const resolveOpts = {strict: false}; var resolveOpts = {strict: false};
relativePaths.forEach(function(relativePath, k) { relativePaths.forEach(function(relativePath, k) {
const resolvedPath = tryResolveAppPath( var resolvedPath = tryResolveAppPath(appRootDir, relativePath, resolveOpts);
appRootDir,
relativePath,
resolveOpts,
);
if (resolvedPath !== undefined) { if (resolvedPath !== undefined) {
relativePaths[k] = resolvedPath; relativePaths[k] = resolvedPath;
} else { } else {
@ -125,28 +121,28 @@ function arrayToObject(array) {
function isPreferredExtension(filename, includeExtensions) { function isPreferredExtension(filename, includeExtensions) {
assert(!!includeExtensions, '"includeExtensions" argument is required'); assert(!!includeExtensions, '"includeExtensions" argument is required');
const ext = path.extname(filename); var 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) {
const results = []; var results = [];
let otherFile; var 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;
} }
const basename = path.basename(filepath, FILE_EXTENSION_JSON); var basename = path.basename(filepath, FILE_EXTENSION_JSON);
const sourceDir = path.dirname(filepath); var sourceDir = path.dirname(filepath);
files.forEach(function(f) { files.forEach(function(f) {
otherFile = path.resolve(sourceDir, f); otherFile = path.resolve(sourceDir, f);
const stats = fs.statSync(otherFile); var stats = fs.statSync(otherFile);
if (stats.isFile()) { if (stats.isFile()) {
const otherFileExtension = path.extname(f); var otherFileExtension = path.extname(f);
if (!(otherFileExtension in getExcludedExtensions()) && if (!(otherFileExtension in getExcludedExtensions()) &&
path.basename(f, otherFileExtension) == basename) { path.basename(f, otherFileExtension) == basename) {
@ -160,9 +156,9 @@ function fixFileExtension(filepath, files, scriptExtensions) {
} }
function resolveAppPath(rootDir, relativePath, resolveOptions) { function resolveAppPath(rootDir, relativePath, resolveOptions) {
const resolvedPath = tryResolveAppPath(rootDir, relativePath, resolveOptions); var resolvedPath = tryResolveAppPath(rootDir, relativePath, resolveOptions);
if (resolvedPath === undefined && !resolveOptions.optional) { if (resolvedPath === undefined && !resolveOptions.optional) {
const err = new Error(g.f('Cannot resolve path "%s"', relativePath)); var err = new Error(g.f('Cannot resolve path "%s"', relativePath));
err.code = 'PATH_NOT_FOUND'; err.code = 'PATH_NOT_FOUND';
throw err; throw err;
} }
@ -170,19 +166,19 @@ function resolveAppPath(rootDir, relativePath, resolveOptions) {
} }
function resolveAppScriptPath(rootDir, relativePath, resolveOptions) { function resolveAppScriptPath(rootDir, relativePath, resolveOptions) {
const resolvedPath = resolveAppPath(rootDir, relativePath, resolveOptions); var resolvedPath = resolveAppPath(rootDir, relativePath, resolveOptions);
if (!resolvedPath) { if (!resolvedPath) {
return false; return false;
} }
const sourceDir = path.dirname(resolvedPath); var sourceDir = path.dirname(resolvedPath);
const files = tryReadDir(sourceDir); var files = tryReadDir(sourceDir);
const fixedFile = fixFileExtension(resolvedPath, files); var fixedFile = fixFileExtension(resolvedPath, files);
return (fixedFile === undefined ? resolvedPath : fixedFile); return (fixedFile === undefined ? resolvedPath : fixedFile);
} }
function tryResolveAppPath(rootDir, relativePath, resolveOptions) { function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
let fullPath; var fullPath;
const start = relativePath.substring(0, 2); var 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
@ -193,7 +189,7 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
*/ */
resolveOptions = resolveOptions || {strict: true}; resolveOptions = resolveOptions || {strict: true};
let isModuleRelative = false; var isModuleRelative = false;
if (relativePath[0] === '/') { if (relativePath[0] === '/') {
fullPath = relativePath; fullPath = relativePath;
} else if (start === './' || start === '..') { } else if (start === './' || start === '..') {
@ -226,17 +222,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. ]
const modulePaths = Module.globalPaths var modulePaths = Module.globalPaths
.concat(Module._nodeModulePaths(rootDir)); .concat(Module._nodeModulePaths(rootDir));
fullPath = modulePaths fullPath = modulePaths
.map(function(candidateDir) { .map(function(candidateDir) {
const absPath = path.join(candidateDir, relativePath); var 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 */
const filePath = new String(require.resolve(absPath)); var filePath = new String(require.resolve(absPath));
filePath.unresolvedPath = absPath; filePath.unresolvedPath = absPath;
return filePath; return filePath;
} catch (err) { } catch (err) {
@ -314,8 +310,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();
const targetArray = currentNames.slice(); var targetArray = currentNames.slice();
let targetIx = targetArray.indexOf(namesToMerge[0]); var 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
@ -325,21 +321,21 @@ function mergePhaseNameLists(currentNames, namesToMerge) {
} }
// merge (zip) two arrays // merge (zip) two arrays
for (let sourceIx = 1; sourceIx < namesToMerge.length; sourceIx++) { for (var sourceIx = 1; sourceIx < namesToMerge.length; sourceIx++) {
const valueToAdd = namesToMerge[sourceIx]; var valueToAdd = namesToMerge[sourceIx];
const previousValue = namesToMerge[sourceIx - 1]; var previousValue = namesToMerge[sourceIx - 1];
const existingIx = targetArray.indexOf(valueToAdd, targetIx); var 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) {
const errMsg = g.f('Ordering conflict: cannot add "%s' + var 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);
} }
const previousIx = targetArray.indexOf(previousValue); var 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,6 +1,9 @@
{ {
"name": "loopback-boot", "name": "loopback-boot",
"version": "3.3.1", "version": "3.2.1",
"publishConfig": {
"tag": "next"
},
"description": "Convention-based bootstrapper for LoopBack applications", "description": "Convention-based bootstrapper for LoopBack applications",
"keywords": [ "keywords": [
"StrongLoop", "StrongLoop",
@ -13,7 +16,7 @@
"url": "https://github.com/strongloop/loopback-boot" "url": "https://github.com/strongloop/loopback-boot"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=6"
}, },
"main": "index.js", "main": "index.js",
"browser": "browser.js", "browser": "browser.js",
@ -26,26 +29,25 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"async": "^2.4.0", "async": "^2.4.0",
"bluebird": "^3.5.3", "bluebird": "^3.4.0",
"commondir": "^1.0.1", "commondir": "^1.0.1",
"debug": "^4.1.1", "debug": "^2.2.0",
"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": "^16.2.3", "browserify": "^4.2.3",
"chai": "^4.2.0", "chai": "^3.5.0",
"coffeeify": "^3.0.1",
"coffeescript": "^2.3.1", "coffeescript": "^2.3.1",
"dirty-chai": "^2.0.1", "coffeeify": "^2.0.1",
"eslint": "^6.6.0", "dirty-chai": "^1.2.2",
"eslint-config-loopback": "^13.1.0", "eslint": "^5.2.0",
"fs-extra": "^7.0.1", "eslint-config-loopback": "^11.0.0",
"fs-extra": "^3.0.1",
"loopback": "^3.0.0", "loopback": "^3.0.0",
"mocha": "^5.2.0", "mocha": "^5.2.0",
"supertest": "^4.0.2" "supertest": "^3.0.0"
}, }
"author": "IBM Corp."
} }

View File

@ -1,22 +1,22 @@
// Copyright IBM Corp. 2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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';
const path = require('path'); var path = require('path');
const loopback = require('loopback'); var loopback = require('loopback');
const chai = require('chai'); var chai = require('chai');
const dirtyChai = require('dirty-chai'); var dirtyChai = require('dirty-chai');
const expect = chai.expect; var expect = chai.expect;
chai.use(dirtyChai); chai.use(dirtyChai);
const bootLoopBackApp = require('..'); const bootLoopBackApp = require('..');
describe('bootLoopBackApp', function() { describe('bootLoopBackApp', function() {
let app; var app;
beforeEach(function() { beforeEach(function() {
app = loopback(); app = loopback();
}); });

View File

@ -1,43 +1,38 @@
// 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';
const path = require('path'); var path = require('path');
const loopback = require('loopback'); var loopback = require('loopback');
const chai = require('chai'); var chai = require('chai');
const dirtyChai = require('dirty-chai'); var dirtyChai = require('dirty-chai');
const expect = chai.expect; var expect = chai.expect;
chai.use(dirtyChai); chai.use(dirtyChai);
const Bootstrapper = require('../lib/bootstrapper'); var Bootstrapper = require('../lib/bootstrapper');
describe('Bootstrapper', function() { describe('Bootstrapper', function() {
let app; var 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) {
const options = { var options = {
app: app, app: app,
appRootDir: path.join(__dirname, './fixtures/simple-app'), appRootDir: path.join(__dirname, './fixtures/simple-app'),
phases: ['load'], phases: ['load'],
}; };
const bootstrapper = new Bootstrapper(options); var bootstrapper = new Bootstrapper(options);
const context = { var 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);
const configs = context.configurations; var 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');
@ -50,22 +45,22 @@ describe('Bootstrapper', function() {
}); });
it('should honor options.plugins', function(done) { it('should honor options.plugins', function(done) {
const options = { var 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'],
}; };
const bootstrapper = new Bootstrapper(options); var bootstrapper = new Bootstrapper(options);
const context = { var 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);
const configs = context.configurations; var configs = context.configurations;
const instructions = context.instructions; var 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();
@ -94,15 +89,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) {
const options = { var 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'],
}; };
const bootstrapper = new Bootstrapper(options); var bootstrapper = new Bootstrapper(options);
const context = { var context = {
app: app, app: app,
}; };

View File

@ -1,22 +1,21 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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';
const boot = require('../'); var boot = require('../');
const async = require('async'); var async = require('async');
const exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox; var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox;
const packageFilter = require('./helpers/browserify').packageFilter; var fs = require('fs');
const fs = require('fs'); var path = require('path');
const path = require('path'); var expect = require('chai').expect;
const expect = require('chai').expect; var browserify = require('browserify');
const browserify = require('browserify'); var sandbox = require('./helpers/sandbox');
const sandbox = require('./helpers/sandbox'); var vm = require('vm');
const vm = require('vm'); var createBrowserLikeContext = require('./helpers/browser').createContext;
const createBrowserLikeContext = require('./helpers/browser').createContext; var printContextLogs = require('./helpers/browser').printContextLogs;
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
@ -24,10 +23,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) {
const app1Dir = path.resolve(__dirname, './fixtures/browser-app'); var app1Dir = path.resolve(__dirname, './fixtures/browser-app');
const app2Dir = path.resolve(__dirname, './fixtures/browser-app-2'); var app2Dir = path.resolve(__dirname, './fixtures/browser-app-2');
const apps = [ var apps = [
{ {
appDir: app1Dir, appDir: app1Dir,
appFile: './app.js', appFile: './app.js',
@ -44,9 +43,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);
const bundledApps = executeBundledApps(bundlePath, apps, function(err) { var bundledApps = executeBundledApps(bundlePath, apps, function(err) {
const app1 = bundledApps.defaultApp; var app1 = bundledApps.defaultApp;
const app2 = bundledApps.browserApp2; var 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');
@ -64,23 +63,22 @@ describe('browser support for multiple apps', function() {
}); });
function browserifyTestApps(apps, next) { function browserifyTestApps(apps, next) {
const b = browserify({ var b = browserify({
debug: true, debug: true,
basedir: path.resolve(__dirname, './fixtures'), basedir: path.resolve(__dirname, './fixtures'),
packageFilter,
}); });
const bundles = []; var bundles = [];
for (const i in apps) { for (var i in apps) {
const appDir = apps[i].appDir; var appDir = apps[i].appDir;
let appFile = apps[i].appFile; var appFile = apps[i].appFile;
const moduleName = apps[i].moduleName; var moduleName = apps[i].moduleName;
const appId = apps[i].appId; var appId = apps[i].appId;
appFile = path.join(appDir, appFile); appFile = path.join(appDir, appFile);
b.require(appFile, {expose: moduleName}); b.require(appFile, {expose: moduleName});
let opts = appDir; var opts = appDir;
if (appId) { if (appId) {
opts = { opts = {
appId: appId, appId: appId,
@ -97,21 +95,21 @@ function browserifyTestApps(apps, next) {
} }
function executeBundledApps(bundlePath, apps, done) { function executeBundledApps(bundlePath, apps, done) {
const code = fs.readFileSync(bundlePath); var code = fs.readFileSync(bundlePath);
const context = createBrowserLikeContext(); var context = createBrowserLikeContext();
vm.runInContext(code, context, bundlePath); vm.runInContext(code, context, bundlePath);
const ids = []; var ids = [];
let script = 'var apps = {};\n'; var script = 'var apps = {};\n';
for (const i in apps) { for (var i in apps) {
const moduleName = apps[i].moduleName; var moduleName = apps[i].moduleName;
const id = apps[i].appId || 'defaultApp'; var 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';
const appsInContext = vm.runInContext(script, context); var 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,39 +1,36 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const boot = require('../'); var boot = require('../');
const exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox; var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox;
const packageFilter = require('./helpers/browserify').packageFilter; var fs = require('fs');
const fs = require('fs'); var path = require('path');
const path = require('path'); var expect = require('chai').expect;
const expect = require('chai').expect; var browserify = require('browserify');
const browserify = require('browserify'); var sandbox = require('./helpers/sandbox');
const sandbox = require('./helpers/sandbox'); var vm = require('vm');
const vm = require('vm'); var createBrowserLikeContext = require('./helpers/browser').createContext;
const createBrowserLikeContext = require('./helpers/browser').createContext; var printContextLogs = require('./helpers/browser').printContextLogs;
const printContextLogs = require('./helpers/browser').printContextLogs;
const compileStrategies = { var compileStrategies = {
default: function(appDir) { default: function(appDir) {
const b = browserify({ var 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) {
const b = browserify({ var b = browserify({
basedir: appDir, basedir: appDir,
extensions: ['.coffee'], extensions: ['.coffee'],
debug: true, debug: true,
packageFilter,
}); });
b.transform('coffeeify'); b.transform('coffeeify');
@ -48,19 +45,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) {
const appDir = path.resolve(__dirname, './fixtures/browser-app'); var 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);
const app = executeBundledApp(bundlePath, function(err) { var 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
@ -72,17 +69,17 @@ describe('browser support', function() {
}); });
it('loads mixins', function(done) { it('loads mixins', function(done) {
const appDir = path.resolve(__dirname, './fixtures/browser-app'); var appDir = path.resolve(__dirname, './fixtures/browser-app');
const options = { var 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);
const app = executeBundledApp(bundlePath, function(err) { var app = executeBundledApp(bundlePath, function(err) {
const modelBuilder = app.registry.modelBuilder; var modelBuilder = app.registry.modelBuilder;
const registry = modelBuilder.mixins.mixins; var 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);
@ -95,18 +92,18 @@ describe('browser support', function() {
// add coffee-script to require.extensions // add coffee-script to require.extensions
require('coffeescript/register'); require('coffeescript/register');
const appDir = path.resolve(__dirname, './fixtures/coffee-app'); var 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);
const app = executeBundledApp(bundlePath, function(err) { var 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();
}); });
@ -122,8 +119,8 @@ function browserifyTestApp(options, strategy, next) {
} }
if (!strategy) strategy = 'default'; if (!strategy) strategy = 'default';
const appDir = typeof options === 'object' ? options.appRootDir : options; var appDir = typeof options === 'object' ? options.appRootDir : options;
const b = compileStrategies[strategy](appDir); var 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);
@ -131,10 +128,10 @@ function browserifyTestApp(options, strategy, next) {
} }
function executeBundledApp(bundlePath, done) { function executeBundledApp(bundlePath, done) {
const code = fs.readFileSync(bundlePath); var code = fs.readFileSync(bundlePath);
const context = createBrowserLikeContext(); var context = createBrowserLikeContext();
vm.runInContext(code, context, bundlePath); vm.runInContext(code, context, bundlePath);
const app = vm.runInContext('require("browser-app")', context); var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const async = require('async'); var async = require('async');
const boot = require('../'); var boot = require('../');
const path = require('path'); var path = require('path');
const loopback = require('loopback'); var loopback = require('loopback');
const assert = require('assert'); var assert = require('assert');
const chai = require('chai'); var chai = require('chai');
const dirtyChai = require('dirty-chai'); var dirtyChai = require('dirty-chai');
const expect = chai.expect; var expect = chai.expect;
chai.use(dirtyChai); chai.use(dirtyChai);
const fs = require('fs-extra'); var fs = require('fs-extra');
const sandbox = require('./helpers/sandbox'); var sandbox = require('./helpers/sandbox');
const appdir = require('./helpers/appdir'); var appdir = require('./helpers/appdir');
const supertest = require('supertest'); var supertest = require('supertest');
const os = require('os'); var os = require('os');
const SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-app'); var SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-app');
const ENV_APP = path.join(__dirname, 'fixtures', 'env-app'); var ENV_APP = path.join(__dirname, 'fixtures', 'env-app');
let app; var 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;
}); });
const dummyInstructions = someInstructions({ var 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');
const UserModel = app.registry.getModel('User'); var 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) {
const file = appdir.writeFileSync('boot/badScript.js', var 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
const actual = loopback.Email.dataSource instanceof loopback.DataSource ? var 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) {
const builtinModel = { var 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() {
let options; var 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);
const modelBuilder = app.registry.modelBuilder; var modelBuilder = app.registry.modelBuilder;
const registry = modelBuilder.mixins.mixins; var 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);
const modelBuilder = app.registry.modelBuilder; var modelBuilder = app.registry.modelBuilder;
const registry = modelBuilder.mixins.mixins; var 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) {
const NAMED_PORT = '\\.\\pipe\\test'; var 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,7 +627,8 @@ 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';
const bootInstructions = simpleMiddlewareConfig('routes', var bootInstructions;
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) {
@ -664,7 +665,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();
}); });
@ -720,10 +721,10 @@ describe('executor', function() {
}); });
it('should not parse invalid config variables', function(done) { it('should not parse invalid config variables', function(done) {
const invalidDataTypes = [undefined, function() { var invalidDataTypes = [undefined, function() {
}]; }];
async.each(invalidDataTypes, function(invalidDataType, cb) { async.each(invalidDataTypes, function(invalidDataType, cb) {
const config = simpleMiddlewareConfig('routes', { var config = simpleMiddlewareConfig('routes', {
path: invalidDataType, path: invalidDataType,
}); });
boot.execute(app, config, function(err) { boot.execute(app, config, function(err) {
@ -741,7 +742,7 @@ describe('executor', function() {
}); });
it('should parse valid config variables', function(done) { it('should parse valid config variables', function(done) {
const config = simpleMiddlewareConfig('routes', { var config = simpleMiddlewareConfig('routes', {
props: ['a', '${vVar}', 1, true, function() { props: ['a', '${vVar}', 1, true, function() {
}, {x: 1, y: '${y}'}], }, {x: 1, y: '${y}'}],
}); });
@ -758,11 +759,11 @@ describe('executor', function() {
}); });
it('should preserve object prototypes', function(done) { it('should preserve object prototypes', function(done) {
const config = simpleMiddlewareConfig( var 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);
@ -782,7 +783,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);
@ -795,12 +796,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) {
const bootInstructions = simpleComponentConfig( var 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
@ -820,8 +821,8 @@ describe('executor', function() {
}); });
it('`env-var` should have precedence over `config`', function(done) { it('`env-var` should have precedence over `config`', function(done) {
const key = 'DYNAMIC_VARIABLE'; var key = 'DYNAMIC_VARIABLE';
const bootInstructions = simpleComponentConfig({ var bootInstructions = simpleComponentConfig({
path: '${restApiRoot}', path: '${restApiRoot}',
isDynamic: '${' + key + '}', isDynamic: '${' + key + '}',
}); });
@ -840,7 +841,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);
@ -855,14 +856,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();
}); });
@ -871,7 +872,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);
@ -887,7 +888,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);
@ -903,7 +904,7 @@ describe('executor', function() {
}); });
it('calls function exported by boot/init.js', function(done) { it('calls function exported by boot/init.js', function(done) {
const file = appdir.writeFileSync('boot/init.js', var 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;
@ -916,7 +917,7 @@ describe('executor', function() {
}); });
it('configures middleware', function(done) { it('configures middleware', function(done) {
const pushNamePath = require.resolve('./helpers/push-name-middleware'); var pushNamePath = require.resolve('./helpers/push-name-middleware');
boot.execute(app, someInstructions({ boot.execute(app, someInstructions({
middleware: { middleware: {
@ -960,7 +961,7 @@ describe('executor', function() {
.get('/') .get('/')
.end(function(err, res) { .end(function(err, res) {
if (err) return done(err); if (err) return done(err);
const names = (res.headers.names || '').split(','); var names = (res.headers.names || '').split(',');
expect(names).to.eql(['initial', 'custom', 'routes']); expect(names).to.eql(['initial', 'custom', 'routes']);
done(); done();
}); });
@ -988,7 +989,7 @@ describe('executor', function() {
.get('/') .get('/')
.end(function(err, res) { .end(function(err, res) {
if (err) return done(err); if (err) return done(err);
const EXPECTED_TEXT = '<!DOCTYPE html>\n<html>\n<head lang="en">\n' + var 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>';
@ -1030,7 +1031,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'});
@ -1051,7 +1052,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();
}); });
@ -1074,14 +1075,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) {
const passportPath = require.resolve('./fixtures/passport'); var passportPath = require.resolve('./fixtures/passport');
boot.execute(app, someInstructions({ boot.execute(app, someInstructions({
middleware: { middleware: {
@ -1121,7 +1122,7 @@ describe('executor', function() {
}); });
describe('when booting with lazy connect', function() { describe('when booting with lazy connect', function() {
const SAMPLE_INSTRUCTION = someInstructions({ var SAMPLE_INSTRUCTION = someInstructions({
dataSources: { dataSources: {
lazyConnector: { lazyConnector: {
connector: 'testLazyConnect', connector: 'testLazyConnect',
@ -1129,7 +1130,7 @@ describe('executor', function() {
}, },
}, },
}); });
let connectTriggered = true; var connectTriggered = true;
beforeEach(function() { beforeEach(function() {
app.connector('testLazyConnect', { app.connector('testLazyConnect', {
@ -1183,14 +1184,14 @@ describe('executor', function() {
}); });
it('should convert dynamic variable for datasource', function(done) { it('should convert dynamic variable for datasource', function(done) {
const datasource = { var datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
port: '${DYNAMIC_PORT}', port: '${DYNAMIC_PORT}',
}, },
}; };
const bootInstructions = {dataSources: datasource}; var 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';
@ -1203,20 +1204,20 @@ describe('executor', function() {
}); });
it('should resolve dynamic config via app.get()', function(done) { it('should resolve dynamic config via app.get()', function(done) {
const datasource = { var datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
}, },
}; };
const bootInstructions = { var 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();
}); });
@ -1224,13 +1225,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';
const datasource = { var datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
}, },
}; };
const bootInstructions = { var bootInstructions = {
application: {DYNAMIC_HOST: '127.0.0.3'}, application: {DYNAMIC_HOST: '127.0.0.3'},
dataSources: datasource, dataSources: datasource,
}; };
@ -1242,13 +1243,13 @@ describe('executor', function() {
}); });
it('empty dynamic conf should resolve as `undefined`', function(done) { it('empty dynamic conf should resolve as `undefined`', function(done) {
const datasource = { var datasource = {
mydb: { mydb: {
connector: 'memory', connector: 'memory',
host: '${DYNAMIC_HOST}', host: '${DYNAMIC_HOST}',
}, },
}; };
const bootInstructions = {dataSources: datasource}; var 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();
@ -1265,7 +1266,7 @@ function simpleMiddlewareConfig(phase, paths, params) {
paths = undefined; paths = undefined;
} }
const config = { var config = {
phase: phase, phase: phase,
params: params, params: params,
}; };
@ -1314,7 +1315,7 @@ assert.isFunc = function(obj, name) {
}; };
function someInstructions(values) { function someInstructions(values) {
const result = { var 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'}},
@ -1327,7 +1328,7 @@ function someInstructions(values) {
result.env = values.env; result.env = values.env;
if (values.files) { if (values.files) {
for (const k in values.files) for (var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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';
const loopback = require('loopback'); var loopback = require('loopback');
const boot = require('../../../'); var boot = require('../../../');
const app = module.exports = loopback(); var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const loopback = require('loopback'); var loopback = require('loopback');
const boot = require('../../../'); var boot = require('../../../');
const app = module.exports = loopback(); var app = module.exports = loopback();
boot(app, __dirname); boot(app, __dirname);

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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';
const framework = { var 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 @@ const framework = {
}, },
}; };
const Passport = function() { var Passport = function() {
this._framework = framework; this._framework = framework;
}; };

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2017. 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';
const Promise = require('bluebird'); var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2017. 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';
const Promise = require('bluebird'); var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2017. 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';
const Promise = require('bluebird'); var 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. 2018,2019. All Rights Reserved. // Copyright IBM Corp. 2017. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,8 +1,3 @@
// 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const path = require('path'); var path = require('path');
const fs = require('fs-extra'); var fs = require('fs-extra');
const extend = require('util')._extend; var extend = require('util')._extend;
const sandbox = require('./sandbox'); var sandbox = require('./sandbox');
const appdir = exports; var appdir = exports;
let PATH = appdir.PATH = null; var 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);
const randomStr = buf.toString('hex'); var 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) {
const filePath = this.resolve(name); var 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,17 +1,16 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved. // Copyright IBM Corp. 2015,2016. 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';
const vm = require('vm'); var vm = require('vm');
function createContext() { function createContext() {
const context = { var context = {
// required by browserify // required by browserify
XMLHttpRequest: function() {}, XMLHttpRequest: function() { throw new Error('not implemented'); },
clearTimeout: function() {},
FormData: function() { throw new Error('not implemented'); }, FormData: function() { throw new Error('not implemented'); },
localStorage: { localStorage: {
@ -33,7 +32,7 @@ function createContext() {
DataView: DataView, DataView: DataView,
crypto: { crypto: {
getRandomValues: function(typedArray) { getRandomValues: function(typedArray) {
const randomBuffer = require('crypto').randomBytes(typedArray.length); var 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.
@ -73,9 +72,9 @@ function createContext() {
exports.createContext = createContext; exports.createContext = createContext;
function printContextLogs(context) { function printContextLogs(context) {
let k, ix; // see https://github.com/eslint/eslint/issues/5744 var k, ix; // see https://github.com/eslint/eslint/issues/5744
for (k in context.console._logs) { for (k in context.console._logs) {
const items = context.console._logs[k]; var 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,2019. All Rights Reserved. // Copyright IBM Corp. 2015. 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';
const fs = require('fs'); var fs = require('fs');
const sandbox = require('./sandbox'); var sandbox = require('./sandbox');
function exportToSandbox(b, fileName, callback) { function exportToSandbox(b, fileName, callback) {
const bundlePath = sandbox.resolve(fileName); var bundlePath = sandbox.resolve(fileName);
const out = fs.createWriteStream(bundlePath); var out = fs.createWriteStream(bundlePath);
b.bundle().pipe(out); b.bundle().pipe(out);
out.on('error', function(err) { out.on('error', function(err) {
@ -21,16 +21,3 @@ 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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,2019. All Rights Reserved. // Copyright IBM Corp. 2014. 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';
const fs = require('fs-extra'); var fs = require('fs-extra');
const path = require('path'); var path = require('path');
const sandbox = exports; var 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() {
const args = Array.prototype.slice.apply(arguments); var 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. 2016,2019. All Rights Reserved. // Copyright IBM Corp. 2014,2016. 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';
const utils = require('../lib/utils'); var utils = require('../lib/utils');
const expect = require('chai').expect; var expect = require('chai').expect;
const sandbox = require('./helpers/sandbox'); var sandbox = require('./helpers/sandbox');
const appdir = require('./helpers/appdir'); var 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() {
const doesNotExist = sandbox.resolve('does-not-exist.json'); var 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() {
const doesExist = appdir.writeConfigFileSync('does-exist.json', { var doesExist = appdir.writeConfigFileSync('does-exist.json', {
exists: true, exists: true,
}); });
expect(utils.fileExistsSync(doesExist)) expect(utils.fileExistsSync(doesExist))