Compare commits
No commits in common. "master" and "v3.1.0" have entirely different histories.
|
@ -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
|
||||||
|
-->
|
|
@ -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_
|
|
|
@ -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.
|
|
|
@ -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/
|
|
||||||
|
|
||||||
-->
|
|
|
@ -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.
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
sudo: false
|
sudo: false
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "8"
|
- "4"
|
||||||
- "10"
|
- "6"
|
||||||
|
- "7"
|
||||||
|
|
||||||
|
|
46
CHANGES.md
46
CHANGES.md
|
@ -1,49 +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
|
|
||||||
=========================
|
|
||||||
|
|
||||||
* fix: set `app.booting` flag immediately (Miroslav Bajtoš)
|
|
||||||
|
|
||||||
* fix: update lodash (jannyHou)
|
|
||||||
|
|
||||||
|
|
||||||
2018-10-18, Version 3.2.0
|
|
||||||
=========================
|
|
||||||
|
|
||||||
* README: update LTS status (Miroslav Bajtoš)
|
|
||||||
|
|
||||||
* Add support for es6 modules for boot scripts (Walker)
|
|
||||||
|
|
||||||
|
|
||||||
2018-07-26, Version 3.1.1
|
|
||||||
=========================
|
|
||||||
|
|
||||||
* update: dependency (jannyHou)
|
|
||||||
|
|
||||||
* chore: update dependencies (Diana Lau)
|
|
||||||
|
|
||||||
* [WebFM] cs/pl/ru translation (candytangnb)
|
|
||||||
|
|
||||||
* chore: update license (Diana Lau)
|
|
||||||
|
|
||||||
* CODEOWNERS: move @lehni to Alumni section (Miroslav Bajtoš)
|
|
||||||
|
|
||||||
* Add support for ES6 style async boot scripts (Jürg Lehni)
|
|
||||||
|
|
||||||
|
|
||||||
2017-10-13, Version 3.1.0
|
2017-10-13, Version 3.1.0
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,4 @@
|
||||||
# Each line is a file pattern followed by one or more owners,
|
# Each line is a file pattern followed by one or more owners,
|
||||||
# the last matching pattern has the most precendence.
|
# the last matching pattern has the most precendence.
|
||||||
|
|
||||||
# Current maintainers
|
* @raymondfeng @lehni @zbarbuto
|
||||||
|
|
||||||
* @raymondfeng @zbarbuto
|
|
||||||
|
|
||||||
# Alumni
|
|
||||||
#
|
|
||||||
# @lehni
|
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) IBM Corp. 2014,2017. All Rights Reserved.
|
Copyright (c) IBM Corp. 2014,2016. All Rights Reserved.
|
||||||
Node module: loopback-boot
|
Node module: loopback-boot
|
||||||
This project is licensed under the MIT License, full text below.
|
This project is licensed under the MIT License, full text below.
|
||||||
|
|
||||||
|
|
27
README.md
27
README.md
|
@ -1,21 +1,11 @@
|
||||||
# LoopBack Boot
|
# LoopBack Boot
|
||||||
|
|
||||||
**⚠️ LoopBack 3 has reached end of life. We are no longer accepting pull requests or providing
|
|
||||||
support for community users. The only exception is fixes for critical bugs and security
|
|
||||||
vulnerabilities provided as part of support for IBM API Connect customers. (See
|
|
||||||
[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
|
|
||||||
soon as possible. Refer to our
|
|
||||||
[Migration Guide](https://loopback.io/doc/en/lb4/migration-overview.html)
|
|
||||||
for more information on how to upgrade.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
A convention-based bootstrapper for LoopBack applications.
|
A convention-based bootstrapper for LoopBack applications.
|
||||||
|
|
||||||
For full documentation, see the official StrongLoop documentation: [Defining boot scripts](https://loopback.io/doc/en/lb2/Defining-boot-scripts) and [Creating a LoopBack application](https://loopback.io/doc/en/lb2/Creating-an-application).
|
For full documentation, see the official StrongLoop documentation: [Defining boot scripts](https://loopback.io/doc/en/lb2/Defining-boot-scripts) and [Creating a LoopBack application](https://loopback.io/doc/en/lb2/Creating-an-application).
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
The loopback-boot module initializes (bootstraps) a LoopBack application. Specifically, it:
|
The loopback-boot module initializes (bootstraps) a LoopBack application. Specifically, it:
|
||||||
- Configures data-sources.
|
- Configures data-sources.
|
||||||
- Defines custom models
|
- Defines custom models
|
||||||
|
@ -56,19 +46,6 @@ app.listen();
|
||||||
See [API docs](http://apidocs.strongloop.com/loopback-boot/) for
|
See [API docs](http://apidocs.strongloop.com/loopback-boot/) for
|
||||||
complete API reference.
|
complete API reference.
|
||||||
|
|
||||||
## Module Long Term Support Policy
|
|
||||||
|
|
||||||
This module adopts the [
|
|
||||||
Module Long Term Support (LTS)](http://github.com/CloudNativeJS/ModuleLTS) policy,
|
|
||||||
with the following End Of Life (EOL) dates:
|
|
||||||
|
|
||||||
| Version | Status | Published | EOL |
|
|
||||||
| ------- | --------------- | --------- | -------- |
|
|
||||||
| 3.x | End-of-Life | May 2017 | Dec 2020 |
|
|
||||||
| 2.x | End-of-Life | Jul 2014 | Apr 2019 |
|
|
||||||
|
|
||||||
Learn more about our LTS plan in [docs](https://loopback.io/doc/en/contrib/Long-term-support.html).
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This module is provided under dual MIT/StrongLoop license. See [LICENSE](LICENSE) for details.
|
This module is provided under dual MIT/StrongLoop license. See [LICENSE](LICENSE) for details.
|
||||||
|
|
14
browser.js
14
browser.js
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
25
index.js
25
index.js
|
@ -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,9 @@ 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']});
|
||||||
);
|
var context = {
|
||||||
const context = {
|
|
||||||
app: app,
|
app: app,
|
||||||
instructions: instructions,
|
instructions: instructions,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"1e5fea50eef843cbffd1d438494912c8": "Nelze vyřešit cestu \"{0}\"",
|
|
||||||
"34319676975b1abf107da7a056abb434": "Neplatný formát normalizace - \"{0}\"",
|
|
||||||
"3a7049e42006e8bc19e0f4fc8df63b6b": "Aplikace `app` je založena na nekompatibilní verzí Loopback {0}. Podporované verze: {1}",
|
|
||||||
"3f93b626dd9a1c33d67490f6e71018b5": "VAROVÁNÍ: Hlavní konfigurační soubor \"{0}{{.json}}\" chybí",
|
|
||||||
"4d052d84c8620730afd4a30832f11724": "Nelze konfigurovat neznámý model {0}",
|
|
||||||
"4ed668e9187650d898acf97707df445a": "Fáze {{phase}} \"{0}\" není definována v hlavní konfiguraci.",
|
|
||||||
"6447e6b342a2c51ab0bc53b3cbdf3742": "Konflikt řazení: Nelze přidat \"{0}\" za \"{1}\", protože již bylo uvedené opačné pořadí",
|
|
||||||
"70654dc6eb565613a33344efed3de998": "Nezdařilo se načíst zaváděcí skript: {0}\n{1}",
|
|
||||||
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} se neinterpretuje na platnou hodnotu, vráceno jako {1}. \"{2}\" musí být rozdělitelný v proměnné prostředí nebo {{app.get()}}.",
|
|
||||||
"91a742b7c3568cf6b6755741a70b3c52": "{{middleware}} \"{0}\" v {{phase}} \"{1}\" není definováno v hlavní konfiguraci.",
|
|
||||||
"a3aa22086ae4976cd013065c9a3ff81c": "Nelze použít {0}: ",
|
|
||||||
"be2cf2868ba54624fe38e9908dde5e9e": "Data v {{model-config.json}} jsou v nepodporovaném formátu {{1.x}}.",
|
|
||||||
"ec551b6f2fafd8d40af801ebe5bb09f6": "Vyřazení pokynů {{middleware}}, klient {{loopback}} nepodporuje {{middleware}}.",
|
|
||||||
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" nelze nalézt: {1}"
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"1e5fea50eef843cbffd1d438494912c8": "Nie można rozstrzygnąć ścieżki \"{0}\"",
|
|
||||||
"34319676975b1abf107da7a056abb434": "Niepoprawny format normalizacji — \"{0}\"",
|
|
||||||
"3a7049e42006e8bc19e0f4fc8df63b6b": "Aplikacja jest obsługiwana przez niezgodną wersję aplikacji LoopBack {0}. Obsługiwane wersje: {1}",
|
|
||||||
"3f93b626dd9a1c33d67490f6e71018b5": "OSTRZEŻENIE: Brak głównego pliku konfiguracyjnego \"{0}{{.json}}\"",
|
|
||||||
"4d052d84c8620730afd4a30832f11724": "Nie można skonfigurować nieznanego modelu {0}",
|
|
||||||
"4ed668e9187650d898acf97707df445a": "Faza {{phase}} \"{0}\" nie została zdefiniowana w konfiguracji głównej.",
|
|
||||||
"6447e6b342a2c51ab0bc53b3cbdf3742": "Konflikt porządkowania: nie można dodać elementu \"{0}\" po elemencie \"{1}\", ponieważ została już określona odwrotna kolejność",
|
|
||||||
"70654dc6eb565613a33344efed3de998": "Nie powiodło się ładowanie skryptu startowego: {0}\n{1}",
|
|
||||||
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} nie umożliwia rozstrzygnięcia na poprawną wartość, zwrócono jako {1}. \"{2}\" musi umożliwiać rozstrzygnięcie w zmiennej środowiskowej lub przez metodę {{app.get()}}.",
|
|
||||||
"91a742b7c3568cf6b6755741a70b3c52": "Warstwa pośrednia {{middleware}} \"{0}\" w fazie {{phase}} \"{1}\" nie została zdefiniowana w konfiguracji głównej.",
|
|
||||||
"a3aa22086ae4976cd013065c9a3ff81c": "Nie można zastosować {0}: ",
|
|
||||||
"be2cf2868ba54624fe38e9908dde5e9e": "Dane w pliku {{model-config.json}} mają nieobsługiwany format {{1.x}}.",
|
|
||||||
"ec551b6f2fafd8d40af801ebe5bb09f6": "Odrzucanie instrukcji warstwy pośredniej {{middleware}}, klient {{loopback}} nie obsługuje warstwy pośredniej {{middleware}}.",
|
|
||||||
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Warstwa pośrednia \"{0}\" nie została znaleziona: {1}"
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"1e5fea50eef843cbffd1d438494912c8": "Не удалось определить путь \"{0}\"",
|
|
||||||
"34319676975b1abf107da7a056abb434": "Недопустимый формат нормализации - \"{0}\"",
|
|
||||||
"3a7049e42006e8bc19e0f4fc8df63b6b": "Приложение `app` создано на основе несовместимой версии loopback {0}. Поддерживаемые версии: {1}",
|
|
||||||
"3f93b626dd9a1c33d67490f6e71018b5": "ПРЕДУПРЕЖДЕНИЕ: отсутствует главный файл конфигурации \"{0}{{.json}}\"",
|
|
||||||
"4d052d84c8620730afd4a30832f11724": "Не удается настроить неизвестную модель {0}",
|
|
||||||
"4ed668e9187650d898acf97707df445a": "Этап {{phase}} \"{0}\" не определен в главной конфигурации.",
|
|
||||||
"6447e6b342a2c51ab0bc53b3cbdf3742": "Конфликт упорядочения: не удается добавить \"{0}\" после \"{1}\", та как уже указан другой порядок",
|
|
||||||
"70654dc6eb565613a33344efed3de998": "Не удалось загрузить сценарий загрузки: {0}\n{1}",
|
|
||||||
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} не удается определить в допустимое значение, возвращено как {1}. \"{2}\" должен определяться как переменная среды или с помощью {{app.get()}}.",
|
|
||||||
"91a742b7c3568cf6b6755741a70b3c52": "{{middleware}} \"{0}\" на этапе {{phase}} \"{1}\"не определено в главной конфигурации.",
|
|
||||||
"a3aa22086ae4976cd013065c9a3ff81c": "Не удается применить {0}: ",
|
|
||||||
"be2cf2868ba54624fe38e9908dde5e9e": "Данные в {{model-config.json}} указаны в неподдерживаемом формате {{1.x}}.",
|
|
||||||
"ec551b6f2fafd8d40af801ebe5bb09f6": "Инструкции {{middleware}} отменяются, клиент {{loopback}} не поддерживает {{middleware}}.",
|
|
||||||
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Не найдено промежуточное ПО \"{0}\": {1}"
|
|
||||||
}
|
|
||||||
|
|
|
@ -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,32 +190,23 @@ 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;
|
||||||
|
var bootPlugins = this.getExtensions('/boot');
|
||||||
if (phases.includes('starting') || phases.includes('start')) {
|
|
||||||
context.app.booting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bootPlugins = this.getExtensions('/boot');
|
|
||||||
async.eachSeries(phases, function(phase, done) {
|
async.eachSeries(phases, function(phase, done) {
|
||||||
debug('Phase %s', phase);
|
debug('Phase %s', phase);
|
||||||
async.eachSeries(bootPlugins, pluginIteratorFactory(context, phase), done);
|
async.eachSeries(bootPlugins, pluginIteratorFactory(context, phase), done);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
if (phases.includes('started')) {
|
|
||||||
context.app.booting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return done(err, context);
|
return done(err, context);
|
||||||
});
|
});
|
||||||
return done.promise;
|
return done.promise;
|
||||||
|
|
|
@ -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,18 @@ 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 +118,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 +127,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});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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}"
|
||||||
|
@ -287,7 +287,7 @@ function getConfigVariable(app, param, useEnvVars) {
|
||||||
configVariable = undefined;
|
configVariable = undefined;
|
||||||
g.warn('%s does not resolve to a valid value, returned as %s. ' +
|
g.warn('%s does not resolve to a valid value, returned as %s. ' +
|
||||||
'"%s" must be resolvable in Environment variable or by {{app.get()}}.',
|
'"%s" must be resolvable in Environment variable or by {{app.get()}}.',
|
||||||
param, configVariable, varName);
|
param, configVariable, varName);
|
||||||
debug('Dynamic Configuration: Cannot resolve variable for `%s`, ' +
|
debug('Dynamic Configuration: Cannot resolve variable for `%s`, ' +
|
||||||
'returned as %s', varName, configVariable);
|
'returned as %s', varName, configVariable);
|
||||||
}
|
}
|
||||||
|
@ -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') {
|
||||||
|
|
|
@ -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;
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,20 +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 +46,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 +64,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 +79,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 +91,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 +105,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 +114,11 @@ function applyAppConfig(app, appConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.prototype.starting = function(context) {
|
Application.prototype.starting = function(context) {
|
||||||
const app = context.app;
|
var app = context.app;
|
||||||
|
app.booting = true;
|
||||||
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,8 @@ 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;
|
||||||
|
app.booting = false;
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
app.emit('booted');
|
app.emit('booted');
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -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,19 +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 (typeof exports === 'function') {
|
if (typeof exports === 'function') {
|
||||||
debug('Exported function detected %s', filepath);
|
debug('Exported function detected %s', filepath);
|
||||||
functions.push({
|
functions.push({
|
||||||
|
@ -82,24 +81,23 @@ 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) {
|
if (f.func.length >= 2) {
|
||||||
debug('Async function %s %s', err ? 'failed' : 'finished', f.path);
|
debug('Starting async function %s', f.path);
|
||||||
done(err);
|
f.func(app, function(err) {
|
||||||
// Make sure done() isn't called twice, e.g. if a script returns a
|
debug('Async function finished %s', f.path);
|
||||||
// thenable object and also calls the passed callback.
|
done(err);
|
||||||
cb = function() {};
|
});
|
||||||
};
|
} else {
|
||||||
try {
|
debug('Starting sync function %s', f.path);
|
||||||
const result = f.func(app, cb);
|
var error;
|
||||||
if (result && typeof result.then === 'function') {
|
try {
|
||||||
result.then(function() { cb(); }, cb);
|
f.func(app);
|
||||||
} else if (f.func.length < 2) {
|
|
||||||
debug('Sync function finished %s', f.path);
|
debug('Sync function finished %s', f.path);
|
||||||
done();
|
} catch (err) {
|
||||||
|
debug('Sync function failed %s', f.path, err);
|
||||||
|
error = err;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
done(error);
|
||||||
debug('Sync function failed %s', f.path, err);
|
|
||||||
done(err);
|
|
||||||
}
|
}
|
||||||
}, callback);
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -23,7 +23,7 @@ function Component(options) {
|
||||||
|
|
||||||
util.inherits(Component, PluginBase);
|
util.inherits(Component, PluginBase);
|
||||||
|
|
||||||
Component.prototype.getRootDir = function() {
|
Component.prototype.getRootDir = function() {
|
||||||
return this.options.componentRootDir || this.options.rootDir;
|
return this.options.componentRootDir || this.options.rootDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
@ -102,19 +102,19 @@ Middleware.prototype.buildInstructions = function(context, rootDir, config) {
|
||||||
if (!resolved.sourceFile) {
|
if (!resolved.sourceFile) {
|
||||||
return g.log('Middleware "%s" not found: %s',
|
return g.log('Middleware "%s" not found: %s',
|
||||||
middleware,
|
middleware,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,31 +30,30 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
* then remove the common directories from `mixinSources` */
|
* then remove the common directories from `mixinSources` */
|
||||||
|
@ -62,33 +61,31 @@ function buildAllMixinInstructions(appRootDir, options, mixinSources,
|
||||||
|
|
||||||
// load mixins from `options.mixinSources`
|
// load mixins from `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 +96,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 +126,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 +165,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 +173,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);
|
||||||
|
|
|
@ -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,38 @@ 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 +83,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 +117,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,15 +145,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) {
|
||||||
debug('Model source code not found: %s - %s', definition.sourceFile);
|
debug('Model source code not found: %s - %s', definition.sourceFile);
|
||||||
|
@ -171,11 +166,11 @@ 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)',
|
||||||
idx);
|
idx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
registry[modelName] = definition;
|
registry[modelName] = definition;
|
||||||
|
@ -185,26 +180,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 +213,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,46 +236,44 @@ 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) {
|
||||||
// 1. Built-in models are exposed on the loopback object
|
// 1. Built-in models are exposed on the loopback object
|
||||||
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 +290,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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
90
lib/utils.js
90
lib/utils.js
|
@ -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 {
|
||||||
|
@ -106,7 +102,7 @@ function getExcludedExtensions() {
|
||||||
return {
|
return {
|
||||||
'.json': '.json',
|
'.json': '.json',
|
||||||
'.node': 'node',
|
'.node': 'node',
|
||||||
/**
|
/**
|
||||||
* This is a temporary workaround for #246
|
* This is a temporary workaround for #246
|
||||||
* See discussion here for full description of the underlying issue
|
* See discussion here for full description of the underlying issue
|
||||||
* https://github.com/strongloop/loopback-boot/pull/245#issuecomment-311052798
|
* https://github.com/strongloop/loopback-boot/pull/245#issuecomment-311052798
|
||||||
|
@ -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
|
||||||
|
|
43
package.json
43
package.json
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-boot",
|
"name": "loopback-boot",
|
||||||
"version": "3.3.1",
|
"version": "3.1.0",
|
||||||
|
"publishConfig": {
|
||||||
|
"tag": "next"
|
||||||
|
},
|
||||||
"description": "Convention-based bootstrapper for LoopBack applications",
|
"description": "Convention-based bootstrapper for LoopBack applications",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"StrongLoop",
|
"StrongLoop",
|
||||||
|
@ -13,39 +16,37 @@
|
||||||
"url": "https://github.com/strongloop/loopback-boot"
|
"url": "https://github.com/strongloop/loopback-boot"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=4.0.0"
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"browser": "browser.js",
|
"browser": "browser.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"posttest": "npm run lint",
|
"posttest": "npm run lint",
|
||||||
"lint": "eslint .",
|
"lint": "eslint ."
|
||||||
"lint:fix": "eslint . --fix"
|
|
||||||
},
|
},
|
||||||
"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.13.1",
|
||||||
"semver": "^5.1.0",
|
"semver": "^5.1.0",
|
||||||
"strong-globalize": "^4.1.1",
|
"strong-globalize": "^3.1.0",
|
||||||
"toposort": "^2.0.2"
|
"toposort": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browserify": "^16.2.3",
|
"browserify": "^4.2.3",
|
||||||
"chai": "^4.2.0",
|
"chai": "^3.5.0",
|
||||||
"coffeeify": "^3.0.1",
|
"coffee-script": "^1.10.0",
|
||||||
"coffeescript": "^2.3.1",
|
"coffeeify": "^2.0.1",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^1.2.2",
|
||||||
"eslint": "^6.6.0",
|
"eslint": "^3.19.0",
|
||||||
"eslint-config-loopback": "^13.1.0",
|
"eslint-config-loopback": "^8.0.0",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^3.0.1",
|
||||||
"loopback": "^3.0.0",
|
"loopback": "^3.0.0",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^3.3.0",
|
||||||
"supertest": "^4.0.2"
|
"supertest": "^3.0.0"
|
||||||
},
|
}
|
||||||
"author": "IBM Corp."
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright IBM Corp. 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';
|
|
||||||
|
|
||||||
const path = require('path');
|
|
||||||
const loopback = require('loopback');
|
|
||||||
|
|
||||||
const chai = require('chai');
|
|
||||||
const dirtyChai = require('dirty-chai');
|
|
||||||
const expect = chai.expect;
|
|
||||||
chai.use(dirtyChai);
|
|
||||||
|
|
||||||
const bootLoopBackApp = require('..');
|
|
||||||
|
|
||||||
describe('bootLoopBackApp', function() {
|
|
||||||
let app;
|
|
||||||
beforeEach(function() {
|
|
||||||
app = loopback();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets app.booting immediately', function() {
|
|
||||||
const appDir = path.join(__dirname, './fixtures/empty-app');
|
|
||||||
|
|
||||||
// Start the bootstrapper
|
|
||||||
const promise = bootLoopBackApp(app, appDir);
|
|
||||||
|
|
||||||
// Still in the original turn of the event loop,
|
|
||||||
// verify that the app is signalling "boot in progress"
|
|
||||||
expect(app.booting).to.equal(true);
|
|
||||||
|
|
||||||
// Wait for bootstrapper to finish
|
|
||||||
return promise.then(() => {
|
|
||||||
// Verify that app is signalling "boot has finished"
|
|
||||||
expect(app.booting).to.equal(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -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();
|
||||||
|
@ -73,48 +68,40 @@ describe('Bootstrapper', function() {
|
||||||
expect(instructions.application, 'application').to.be.an('object');
|
expect(instructions.application, 'application').to.be.an('object');
|
||||||
expect(instructions.tracker, 'instruction: tracker').to.eql('compile');
|
expect(instructions.tracker, 'instruction: tracker').to.eql('compile');
|
||||||
expect(context.executions.tracker, 'execution: tracker').to.eql('start');
|
expect(context.executions.tracker, 'execution: tracker').to.eql('start');
|
||||||
expect(process.bootFlags, 'process: bootFlags').to.eql([
|
expect(process.bootFlags, 'process: bootFlags').to.eql(['barLoaded',
|
||||||
'barLoaded',
|
|
||||||
'barSyncLoaded',
|
'barSyncLoaded',
|
||||||
'fooLoaded',
|
'fooLoaded',
|
||||||
'promiseLoaded',
|
|
||||||
'thenableLoaded',
|
|
||||||
'barStarted',
|
'barStarted',
|
||||||
'barFinished',
|
'barFinished',
|
||||||
'barSyncExecuted',
|
'barSyncExecuted',
|
||||||
'promiseStarted',
|
|
||||||
'promiseFinished',
|
|
||||||
'thenableStarted',
|
|
||||||
'thenableFinished',
|
|
||||||
'umdLoaded',
|
|
||||||
]);
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
bootstrapper.run(context, function(err) {
|
bootstrapper.run(context, function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(process.bootFlags, 'process: bootFlags').to.eql([
|
expect(process.bootFlags, 'process: bootFlags').to.eql([
|
||||||
'customjs',
|
'customjs',
|
||||||
'customjs2',
|
'customjs2',
|
||||||
]);
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
delete process.bootFlags;
|
delete process.bootFlags;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,20 +45,18 @@ 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)
|
||||||
'_customized',
|
.to.have.property('_customized', 'Customer');
|
||||||
'Customer',
|
|
||||||
);
|
|
||||||
|
|
||||||
// configured in fixtures/browser-app/component-config.json
|
// configured in fixtures/browser-app/component-config.json
|
||||||
// and fixtures/browser-app/components/dummy-component.js
|
// and fixtures/browser-app/components/dummy-component.js
|
||||||
|
@ -72,17 +67,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);
|
||||||
|
|
||||||
|
@ -93,21 +88,19 @@ describe('browser support', function() {
|
||||||
|
|
||||||
it('supports coffee-script files', function(done) {
|
it('supports coffee-script files', function(done) {
|
||||||
// add coffee-script to require.extensions
|
// add coffee-script to require.extensions
|
||||||
require('coffeescript/register');
|
require('coffee-script/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)
|
||||||
'_customized',
|
.to.have.property('_customized', 'Customer');
|
||||||
'Customer',
|
|
||||||
);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -116,14 +109,15 @@ describe('browser support', function() {
|
||||||
|
|
||||||
function browserifyTestApp(options, strategy, next) {
|
function browserifyTestApp(options, strategy, next) {
|
||||||
// set default args
|
// set default args
|
||||||
if (typeof strategy === 'function' && !next) {
|
if (((typeof strategy) === 'function') && !next) {
|
||||||
next = strategy;
|
next = strategy;
|
||||||
strategy = undefined;
|
strategy = undefined;
|
||||||
}
|
}
|
||||||
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 +125,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
|
@ -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'),
|
||||||
|
@ -306,16 +306,9 @@ describe('executor', function() {
|
||||||
'barLoaded',
|
'barLoaded',
|
||||||
'barSyncLoaded',
|
'barSyncLoaded',
|
||||||
'fooLoaded',
|
'fooLoaded',
|
||||||
'promiseLoaded',
|
|
||||||
'thenableLoaded',
|
|
||||||
'barStarted',
|
'barStarted',
|
||||||
'barFinished',
|
'barFinished',
|
||||||
'barSyncExecuted',
|
'barSyncExecuted',
|
||||||
'promiseStarted',
|
|
||||||
'promiseFinished',
|
|
||||||
'thenableStarted',
|
|
||||||
'thenableFinished',
|
|
||||||
'umdLoaded',
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -329,132 +322,60 @@ describe('executor', function() {
|
||||||
'barLoaded',
|
'barLoaded',
|
||||||
'barSyncLoaded',
|
'barSyncLoaded',
|
||||||
'fooLoaded',
|
'fooLoaded',
|
||||||
'promiseLoaded',
|
|
||||||
'thenableLoaded',
|
|
||||||
'barStarted',
|
'barStarted',
|
||||||
'barFinished',
|
'barFinished',
|
||||||
'barSyncExecuted',
|
'barSyncExecuted',
|
||||||
'promiseStarted',
|
|
||||||
'promiseFinished',
|
|
||||||
'thenableStarted',
|
|
||||||
'thenableFinished',
|
|
||||||
'umdLoaded',
|
|
||||||
]);
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('with boot script returning a rejected promise', function() {
|
describe('for mixins', function() {
|
||||||
before(function() {
|
var options;
|
||||||
// Tell simple-app/boot/reject.js to return a rejected promise
|
beforeEach(function() {
|
||||||
process.rejectPromise = true;
|
appdir.writeFileSync('custom-mixins/example.js',
|
||||||
});
|
'module.exports = ' +
|
||||||
|
'function(Model, options) {}');
|
||||||
|
|
||||||
after(function() {
|
appdir.writeFileSync('custom-mixins/time-stamps.js',
|
||||||
delete process.rejectPromise;
|
'module.exports = ' +
|
||||||
});
|
'function(Model, options) {}');
|
||||||
|
|
||||||
it('receives rejected promise as callback error',
|
appdir.writeConfigFileSync('custom-mixins/time-stamps.json', {
|
||||||
function(done) {
|
name: 'Timestamping',
|
||||||
simpleAppInstructions(function(err, context) {
|
});
|
||||||
if (err) return done(err);
|
|
||||||
boot.execute(app, context.instructions, function(err) {
|
options = {
|
||||||
expect(err).to.exist.and.be.an.instanceOf(Error)
|
appRootDir: appdir.PATH,
|
||||||
.with.property('message', 'reject');
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('defines mixins from instructions - using `mixinDirs`',
|
||||||
|
function(done) {
|
||||||
|
options.mixinDirs = ['./custom-mixins'];
|
||||||
|
boot(app, options, function(err) {
|
||||||
|
if (err) return done(err);
|
||||||
|
var modelBuilder = app.registry.modelBuilder;
|
||||||
|
var registry = modelBuilder.mixins.mixins;
|
||||||
|
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with boot script throwing an error', function() {
|
it('defines mixins from instructions - using `mixinSources`',
|
||||||
before(function() {
|
function(done) {
|
||||||
// Tell simple-app/boot/throw.js to throw an error
|
options.mixinSources = ['./custom-mixins'];
|
||||||
process.throwError = true;
|
boot(app, options, function(err) {
|
||||||
});
|
if (err) return done(err);
|
||||||
|
|
||||||
after(function() {
|
var modelBuilder = app.registry.modelBuilder;
|
||||||
delete process.throwError;
|
var registry = modelBuilder.mixins.mixins;
|
||||||
});
|
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
|
||||||
|
|
||||||
it('receives thrown error as callback errors',
|
|
||||||
function(done) {
|
|
||||||
simpleAppInstructions(function(err, context) {
|
|
||||||
if (err) return done(err);
|
|
||||||
boot.execute(app, context.instructions, function(err) {
|
|
||||||
expect(err).to.exist.and.be.an.instanceOf(Error)
|
|
||||||
.with.property('message', 'throw');
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with boot script returning a promise and calling callback',
|
|
||||||
function() {
|
|
||||||
before(function() {
|
|
||||||
process.promiseAndCallback = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function() {
|
|
||||||
delete process.promiseAndCallback;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only call the callback once', function(done) {
|
|
||||||
simpleAppInstructions(function(err, context) {
|
|
||||||
if (err) return done(err);
|
|
||||||
// Note: Mocha will fail this test if done() is called twice
|
|
||||||
boot.execute(app, context.instructions, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for mixins', function() {
|
|
||||||
let options;
|
|
||||||
beforeEach(function() {
|
|
||||||
appdir.writeFileSync('custom-mixins/example.js',
|
|
||||||
'module.exports = ' +
|
|
||||||
'function(Model, options) {}');
|
|
||||||
|
|
||||||
appdir.writeFileSync('custom-mixins/time-stamps.js',
|
|
||||||
'module.exports = ' +
|
|
||||||
'function(Model, options) {}');
|
|
||||||
|
|
||||||
appdir.writeConfigFileSync('custom-mixins/time-stamps.json', {
|
|
||||||
name: 'Timestamping',
|
|
||||||
});
|
|
||||||
|
|
||||||
options = {
|
|
||||||
appRootDir: appdir.PATH,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('defines mixins from instructions - using `mixinDirs`',
|
|
||||||
function(done) {
|
|
||||||
options.mixinDirs = ['./custom-mixins'];
|
|
||||||
boot(app, options, function(err) {
|
|
||||||
if (err) return done(err);
|
|
||||||
const modelBuilder = app.registry.modelBuilder;
|
|
||||||
const registry = modelBuilder.mixins.mixins;
|
|
||||||
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('defines mixins from instructions - using `mixinSources`',
|
|
||||||
function(done) {
|
|
||||||
options.mixinSources = ['./custom-mixins'];
|
|
||||||
boot(app, options, function(err) {
|
|
||||||
if (err) return done(err);
|
|
||||||
|
|
||||||
const modelBuilder = app.registry.modelBuilder;
|
|
||||||
const registry = modelBuilder.mixins.mixins;
|
|
||||||
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with PaaS and npm env variables', function() {
|
describe('with PaaS and npm env variables', function() {
|
||||||
|
@ -581,7 +502,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) {
|
||||||
|
@ -599,7 +520,8 @@ describe('executor', function() {
|
||||||
|
|
||||||
it('should parse a simple config variable', function(done) {
|
it('should parse a simple config variable', function(done) {
|
||||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{path: '${restApiRoot}'}), function(err) {
|
{path: '${restApiRoot}'}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
supertest(app).get('/').end(function(err, res) {
|
supertest(app).get('/').end(function(err, res) {
|
||||||
|
@ -613,7 +535,8 @@ describe('executor', function() {
|
||||||
it('should parse simple config variable from env var', function(done) {
|
it('should parse simple config variable from env var', function(done) {
|
||||||
process.env.restApiRoot = '/url-from-env-var';
|
process.env.restApiRoot = '/url-from-env-var';
|
||||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{path: '${restApiRoot}'}), function(err) {
|
{path: '${restApiRoot}'}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
supertest(app).get('/url-from-env-var').end(function(err, res) {
|
supertest(app).get('/url-from-env-var').end(function(err, res) {
|
||||||
|
@ -627,7 +550,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) {
|
||||||
|
@ -644,7 +568,8 @@ describe('executor', function() {
|
||||||
|
|
||||||
it('should parse multiple config variables', function(done) {
|
it('should parse multiple config variables', function(done) {
|
||||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{path: '${restApiRoot}', env: '${env}'}), function(err) {
|
{path: '${restApiRoot}', env: '${env}'}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
supertest(app).get('/').end(function(err, res) {
|
supertest(app).get('/').end(function(err, res) {
|
||||||
|
@ -658,13 +583,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, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{paths: ['${restApiRoot}']}), function(err) {
|
{paths: ['${restApiRoot}']}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
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();
|
||||||
});
|
});
|
||||||
|
@ -673,7 +599,8 @@ 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, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{info: {path: '${restApiRoot}'}}), function(err) {
|
{info: {path: '${restApiRoot}'}}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
supertest(app).get('/').end(function(err, res) {
|
supertest(app).get('/').end(function(err, res) {
|
||||||
|
@ -688,7 +615,8 @@ 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, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{nested: {info: {path: '${restApiRoot}'}}}), function(err) {
|
{nested: {info: {path: '${restApiRoot}'}}}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
supertest(app).get('/').end(function(err, res) {
|
supertest(app).get('/').end(function(err, res) {
|
||||||
|
@ -703,7 +631,8 @@ describe('executor', function() {
|
||||||
|
|
||||||
it('should parse config variables with null values', function(done) {
|
it('should parse config variables with null values', function(done) {
|
||||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||||
{nested: {info: {path: '${restApiRoot}', some: null}}}), function(err) {
|
{nested: {info: {path: '${restApiRoot}', some: null}}}
|
||||||
|
), function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
supertest(app).get('/').end(function(err, res) {
|
supertest(app).get('/').end(function(err, res) {
|
||||||
|
@ -720,10 +649,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 +670,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,12 +687,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 +710,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 +723,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 +748,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 +768,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 +783,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 +799,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 +815,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 +831,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 +844,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 +888,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 +916,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,8 +958,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'});
|
||||||
done();
|
done();
|
||||||
|
@ -1051,37 +978,35 @@ 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('disables component if overrided by production configuration',
|
it('disables component if overrided by production configuration',
|
||||||
function(done) {
|
function(done) {
|
||||||
appdir.writeConfigFileSync('component-config.json', {
|
appdir.writeConfigFileSync('component-config.json', {
|
||||||
'./components/test-component': {},
|
'./components/test-component': {},
|
||||||
});
|
});
|
||||||
appdir.writeConfigFileSync('component-config.production.json', {
|
appdir.writeConfigFileSync('component-config.production.json', {
|
||||||
'./components/test-component': null,
|
'./components/test-component': null,
|
||||||
});
|
|
||||||
|
|
||||||
appdir.writeFileSync('components/test-component/index.js',
|
|
||||||
'module.exports = ' +
|
|
||||||
'function(app, options) { app.componentOptions = options; }');
|
|
||||||
|
|
||||||
boot(app, {appRootDir: appdir.PATH, env: 'production'}, function(err) {
|
|
||||||
if (err) return done(err);
|
|
||||||
|
|
||||||
expect(Object.keys(require.cache)).to.not.include(
|
|
||||||
appdir.resolve('components/test-component/index.js'),
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
appdir.writeFileSync('components/test-component/index.js',
|
||||||
|
'module.exports = ' +
|
||||||
|
'function(app, options) { app.componentOptions = options; }');
|
||||||
|
|
||||||
|
boot(app, {appRootDir: appdir.PATH, env: 'production'}, function(err) {
|
||||||
|
if (err) return done(err);
|
||||||
|
|
||||||
|
expect(Object.keys(require.cache)).to.not.include(
|
||||||
|
appdir.resolve('components/test-component/index.js'));
|
||||||
|
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 +1046,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 +1054,7 @@ describe('executor', function() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let connectTriggered = true;
|
var connectTriggered = true;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
app.connector('testLazyConnect', {
|
app.connector('testLazyConnect', {
|
||||||
|
@ -1183,14 +1108,13 @@ 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',
|
|
||||||
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,34 +1127,27 @@ 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: {host: '${DYNAMIC_HOST}'},
|
||||||
connector: 'memory',
|
|
||||||
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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
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: {host: '${DYNAMIC_HOST}'},
|
||||||
connector: 'memory',
|
|
||||||
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 +1159,10 @@ 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: {host: '${DYNAMIC_HOST}'},
|
||||||
connector: 'memory',
|
|
||||||
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 +1179,7 @@ function simpleMiddlewareConfig(phase, paths, params) {
|
||||||
paths = undefined;
|
paths = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = {
|
var config = {
|
||||||
phase: phase,
|
phase: phase,
|
||||||
params: params,
|
params: params,
|
||||||
};
|
};
|
||||||
|
@ -1314,7 +1228,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 +1241,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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
{
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
// Copyright IBM Corp. 2017,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';
|
|
||||||
|
|
||||||
const Promise = require('bluebird');
|
|
||||||
|
|
||||||
module.exports = function(app, callback) {
|
|
||||||
callback();
|
|
||||||
if (process.promiseAndCallback) {
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright IBM Corp. 2017,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';
|
|
||||||
|
|
||||||
const Promise = require('bluebird');
|
|
||||||
|
|
||||||
process.bootFlags.push('promiseLoaded');
|
|
||||||
module.exports = function(app) {
|
|
||||||
process.bootFlags.push('promiseStarted');
|
|
||||||
return Promise.resolve({
|
|
||||||
then: function(onFulfill, onReject) {
|
|
||||||
process.nextTick(function() {
|
|
||||||
process.bootFlags.push('promiseFinished');
|
|
||||||
onFulfill();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,14 +0,0 @@
|
||||||
// Copyright IBM Corp. 2017,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';
|
|
||||||
|
|
||||||
const Promise = require('bluebird');
|
|
||||||
|
|
||||||
module.exports = function(app) {
|
|
||||||
if (process.rejectPromise) {
|
|
||||||
return Promise.reject(new Error('reject'));
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright IBM Corp. 2017. 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';
|
|
||||||
|
|
||||||
process.bootFlags.push('thenableLoaded');
|
|
||||||
module.exports = function(app) {
|
|
||||||
process.bootFlags.push('thenableStarted');
|
|
||||||
return {
|
|
||||||
then: function(onFulfill, onReject) {
|
|
||||||
process.nextTick(function() {
|
|
||||||
process.bootFlags.push('thenableFinished');
|
|
||||||
onFulfill();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,12 +0,0 @@
|
||||||
// Copyright IBM Corp. 2017. 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';
|
|
||||||
|
|
||||||
module.exports = function(app) {
|
|
||||||
if (process.throwError) {
|
|
||||||
throw new Error('throw');
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Copyright IBM Corp. 2018,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';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
default: function() {
|
|
||||||
process.bootFlags.push('umdLoaded');
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Object.defineProperty(module.exports, '__esModule', {value: true});
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in New Issue