diff --git a/.eslintrc.js b/.eslintrc.js index c456b2910..52b9f6836 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,69 +1,78 @@ module.exports = { - "env": { - "node": true, - "es6": true - }, - "parserOptions": { - "ecmaVersion": 8 - }, - "extends": ["eslint:recommended", "google"], - "plugins": [ - "jsdoc" - ], - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "double", - { "allowTemplateLiterals": true } - ], - "semi": [ - "error", - "always" - ], - "no-negated-condition": "off", - "require-jsdoc": "off", - "no-mixed-requires": "off", - "max-len": ["warn", 120], - "no-implicit-coercion": [ - 2, - { "allow": ["!!"] } - ], - "comma-dangle": "off", - "no-tabs": "off", - "valid-jsdoc": 0, - "jsdoc/check-examples": 2, - "jsdoc/check-param-names": 2, - "jsdoc/check-tag-names": 2, - "jsdoc/check-types": 2, - "jsdoc/newline-after-description": 2, - "jsdoc/no-undefined-types": 0, - "jsdoc/require-description": 0, - "jsdoc/require-description-complete-sentence": 0, - "jsdoc/require-example": 0, - "jsdoc/require-hyphen-before-param-description": 0, - "jsdoc/require-param": 2, - "jsdoc/require-param-description": 0, - "jsdoc/require-param-name": 2, - "jsdoc/require-param-type": 2, - "jsdoc/require-returns": 0, - "jsdoc/require-returns-description": 0, - "jsdoc/require-returns-type": 2, - "jsdoc/valid-types": 0 - }, - "settings": { - "jsdoc": { - "tagNamePreference": { - "return": "returns" - } - } - }, - "root": true + "env": { + "node": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 8 + }, + "extends": ["eslint:recommended", "google"], + "plugins": [ + "jsdoc" + ], + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double", + {"allowTemplateLiterals": true} + ], + "semi": [ + "error", + "always" + ], + "no-negated-condition": "off", + "require-jsdoc": "off", + "no-mixed-requires": "off", + "max-len": [ + "error", + { + "code": 120, + "ignoreUrls": true, + "ignoreRegExpLiterals": true + } + ], + "no-implicit-coercion": [ + 2, + {"allow": ["!!"]} + ], + "comma-dangle": "off", + "no-tabs": "off", + "valid-jsdoc": 0, + // jsdoc/check-examples is temporarily set to "warn" as the rule causes issues in our CI + // See: https://github.com/gajus/eslint-plugin-jsdoc/issues/508 + "jsdoc/check-examples": 1, + "jsdoc/check-param-names": 2, + "jsdoc/check-tag-names": 2, + "jsdoc/check-types": 2, + "jsdoc/newline-after-description": 2, + "jsdoc/no-undefined-types": 0, + "jsdoc/require-description": 0, + "jsdoc/require-description-complete-sentence": 0, + "jsdoc/require-example": 0, + "jsdoc/require-hyphen-before-param-description": 0, + "jsdoc/require-param": 2, + "jsdoc/require-param-description": 0, + "jsdoc/require-param-name": 2, + "jsdoc/require-param-type": 2, + "jsdoc/require-returns": 0, + "jsdoc/require-returns-description": 0, + "jsdoc/require-returns-type": 2, + "jsdoc/valid-types": 0 + }, + "settings": { + "jsdoc": { + "tagNamePreference": { + "return": "returns" + } + } + }, + "root": true }; diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 985bd1bea..d0c440ed2 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,37 +1,3 @@ - +## 🚨 Issues Have Been Transferred to UI5 Tooling Repository -## Expected Behavior -{...} - -## Current Behavior -{...} - -## Steps to reproduce the issue -1. {...} -2. {...} -3. {...} - -## Context -- UI5 Module Version *(output of `ui5 --version` when using the CLI)*: `{...}` -- Node.js Version: `{...}` -- npm Version: `{...}` -- OS/Platform: `{...}` -- Browser *(if relevant)*: `{...}` -- Other information: `{...}` - -## Affected components *(if known)* - -- [X] [ui5-builder](https://github.com/SAP/ui5-builder) -- [ ] [ui5-server](https://github.com/SAP/ui5-server) -- [ ] [ui5-cli](https://github.com/SAP/ui5-cli) -- [ ] [ui5-fs](https://github.com/SAP/ui5-fs) -- [ ] [ui5-project](https://github.com/SAP/ui5-project) -- [ ] [ui5-logger](https://github.com/SAP/ui5-logger) - -## Log Output / Stack Trace -``` -{...} -``` +Please create new issues in the UI5 Tooling repository: https://github.com/SAP/ui5-tooling/issues/new/choose diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..afeecf17b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Report UI5 Tooling Issues or Request a Feature + url: https://github.com/SAP/ui5-tooling/issues/new/choose + about: Please create new issues in the UI5 Tooling repository diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..0ae386e6a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: +- package-ecosystem: npm + directory: "/" + schedule: + interval: weekly + day: sunday + time: "10:00" + timezone: Etc/UCT + reviewers: + - matz3 + - RandomByte + versioning-strategy: increase diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..924b1cd65 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,36 @@ +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Execute at least once per week to get new findings without active development taking place + schedule: + - cron: '42 18 * * 6' + +jobs: + codeql-analyze: + name: "CodeQL Analyze" + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: 'javascript' + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml new file mode 100644 index 000000000..932ab27fd --- /dev/null +++ b/.github/workflows/github-ci.yml @@ -0,0 +1,31 @@ +name: GitHub CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + name: General checks, tests and coverage reporting + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@v2 + + - name: Use Node.js LTS 14.x + uses: actions/setup-node@v1 + with: + node-version: 14.x + + - name: Install dependencies + run: npm ci + + - name: Perform checks and tests + run: npm test + + - name: Send report to Coveralls + uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/reuse-compliance.yml b/.github/workflows/reuse-compliance.yml new file mode 100644 index 000000000..1ecfdb5d0 --- /dev/null +++ b/.github/workflows/reuse-compliance.yml @@ -0,0 +1,16 @@ +name: REUSE + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + compliance-check: + name: Compliance Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Execute REUSE Compliance Check + uses: fsfe/reuse-action@v1.1 diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 000000000..3098a4195 --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,33 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: ui5-builder +Upstream-Contact: SAP OpenUI5 +Source: https://github.com/SAP/ui5-builder +Disclaimer: The code in this project may include calls to APIs (“API Calls”) of + SAP or third-party products or services developed outside of this project + (“External Products”). + “APIs” means application programming interfaces, as well as their respective + specifications and implementing code that allows software to communicate with + other software. + API Calls to External Products are not licensed under the open source license + that governs this project. The use of such API Calls and related External + Products are subject to applicable additional agreements with the relevant + provider of the External Products. In no event shall the open source license + that governs this project grant any rights in or to any External Products,or + alter, expand or supersede any terms of the applicable additional agreements. + If you have a valid license agreement with SAP for the use of a particular SAP + External Product, then you may make use of any API Calls included in this + project’s code for that SAP External Product, subject to the terms of such + license agreement. If you do not have a valid license agreement for the use of + a particular SAP External Product, then you may only make use of any API Calls + in this project for that SAP External Product for your internal, non-productive + and non-commercial test and evaluation of such API Calls. Nothing herein grants + you any rights to use or access any SAP External Product, or provide any third + parties the right to use of access any SAP External Product, through API Calls. + +Files: * +Copyright: 2018-2020 SAP SE or an SAP affiliate company and UI5 Tooling contributors +License: Apache-2.0 + +Files: lib/processors/jsdoc/lib/* +Copyright: 2009-2020 SAP SE or an SAP affiliate company and OpenUI5 contributors +License: Apache-2.0 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ae6518680..000000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: node_js # don't install any environment - -node_js: -- "lts/*" - -script: npm run coverage - -after_script: -- if [[ "$TRAVIS_OS_NAME" == "linux" && - (( -n "$TRAVIS_PULL_REQUEST" && "$TRAVIS_PULL_REQUEST" != "false" ) || "$TRAVIS_BRANCH" == "master" ) ]]; then - npm run report-coveralls; - fi - -notifications: - webhooks: https://coveralls.io/webhook diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c9b0fc08..4d007aff1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,216 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v1.5.3...HEAD). +A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v2.4.5...HEAD). + + +## [v2.4.5] - 2020-11-30 +### Bug Fixes +- **generateResourcesJson:** Make resources.json generation deterministic [`41d3335`](https://github.com/SAP/ui5-builder/commit/41d3335bbddaba2e65e3293b37f89010ab0cd6fc) +- **manifestCreator:** Only list components with corresponding 'embeddedBy' ([#555](https://github.com/SAP/ui5-builder/issues/555)) [`89872d7`](https://github.com/SAP/ui5-builder/commit/89872d79623accad1ed148034c1f2fe46e44eeee) + + + +## [v2.4.4] - 2020-11-25 +### Bug Fixes +- **JSModuleAnalyzer:** Properly handle jQuery.sap.registerPreloadedModules calls [`9433f6a`](https://github.com/SAP/ui5-builder/commit/9433f6a989d6fea46f637ac8ff58c739977f456c) + + + +## [v2.4.3] - 2020-11-06 + + +## [v2.4.2] - 2020-11-04 +### Reverts +- [FEATURE] Switch XML minifier from pretty-data to minify-xml + + + +## [v2.4.1] - 2020-11-03 +### Dependency Updates +- Bump minify-xml from 2.1.2 to 2.1.3 [`839d12b`](https://github.com/SAP/ui5-builder/commit/839d12b0b4150ef13c86e639576e5a29854dc7d9) + + + +## [v2.4.0] - 2020-11-03 +### Features +- Tag bundles and ignore them in uglify task ([#535](https://github.com/SAP/ui5-builder/issues/535)) [`b487366`](https://github.com/SAP/ui5-builder/commit/b4873663ea67fa16f8fd9c2672c647026894ba32) +- Switch XML minifier from pretty-data to minify-xml [`be29520`](https://github.com/SAP/ui5-builder/commit/be295203cf71740f0585ee59f44c55ee59e41b26) + + + +## [v2.3.0] - 2020-10-22 +### Features +- Create designtime and support bundles for libraries ([#529](https://github.com/SAP/ui5-builder/issues/529)) [`2a51943`](https://github.com/SAP/ui5-builder/commit/2a5194346279279a6fb28c7332245e1cc5360d63) + +### Performance Improvements +- **BundleWriter:** Improve performance ([#534](https://github.com/SAP/ui5-builder/issues/534)) [`750b43e`](https://github.com/SAP/ui5-builder/commit/750b43eb88aded89eb8cd0b4b9ccb1ca5d5f94d2) + + + +## [v2.2.1] - 2020-10-06 +### Bug Fixes +- **Bundler:** Improve error log messages ([#466](https://github.com/SAP/ui5-builder/issues/466)) [`6bb6235`](https://github.com/SAP/ui5-builder/commit/6bb6235464b54da4e13553ecf9e0fe0ebcb3fe61) +- **tasks/generateResourcesJson:** Handling for sap.ui.integration [`1191b3d`](https://github.com/SAP/ui5-builder/commit/1191b3d4fac9ab7b78467d254afa88041962c416) + +### Dependency Updates +- Bump terser from 4.8.0 to 5.2.1 ([#511](https://github.com/SAP/ui5-builder/issues/511)) [`18f0df8`](https://github.com/SAP/ui5-builder/commit/18f0df84d7f3f4c7de9b1cacf06a5f5d2f0de8a9) + + + +## [v2.2.0] - 2020-09-02 +### Bug Fixes +- SapUiDefine call should not fail when there's no factory function ([#491](https://github.com/SAP/ui5-builder/issues/491)) [`25c6a3c`](https://github.com/SAP/ui5-builder/commit/25c6a3c9cae0d41f2757a8f0641bc043e171201b) + +### Features +- Add generateResourcesJson task ([#390](https://github.com/SAP/ui5-builder/issues/390)) [`021f439`](https://github.com/SAP/ui5-builder/commit/021f439e4125403d0d9e2fa0b7bcd3174ceb46e6) + + + +## [v2.1.0] - 2020-08-11 +### Features +- Implement TaskUtil class [`a7074ae`](https://github.com/SAP/ui5-builder/commit/a7074aeb8167330fd1b6d30bf5b387a212cd6b1b) +- **generateFlexChangesBundle:** Hide bundle input from build result [`001183a`](https://github.com/SAP/ui5-builder/commit/001183a4981bb5fe43039cedfbea70c2090b24db) + + + +## [v2.0.7] - 2020-08-10 +### Bug Fixes +- **generateLibraryPreload:** Ignore missing modules ([#481](https://github.com/SAP/ui5-builder/issues/481)) [`97b339f`](https://github.com/SAP/ui5-builder/commit/97b339f9c5dbddc8b80ed11c68f557d4eddc7f0a) + +### Dependency Updates +- Pin estraverse to v5.1.0 [`e5bc455`](https://github.com/SAP/ui5-builder/commit/e5bc4552015b71678102fd922609ef184502410c) + + + +## [v2.0.6] - 2020-07-21 +### Bug Fixes +- **SmartTemplateAnalyzer:** Do not throw in case missing dependency is expected ([#479](https://github.com/SAP/ui5-builder/issues/479)) [`b2150c3`](https://github.com/SAP/ui5-builder/commit/b2150c303fb14cd07b1f1ecadd1db5117cc7dccf) + + + +## [v2.0.5] - 2020-07-14 +### Bug Fixes +- **Node.js API:** TypeScript type definition support ([#475](https://github.com/SAP/ui5-builder/issues/475)) [`7858810`](https://github.com/SAP/ui5-builder/commit/785881061fe72e25230573ffb6b2a440d6782792) +- **XMLTemplateAnalyzer:** Handle empty XML view/fragment ([#471](https://github.com/SAP/ui5-builder/issues/471)) [`7488d5f`](https://github.com/SAP/ui5-builder/commit/7488d5f2c9216ac87e47ac7019fbc18674e86e30) + + + +## [v2.0.4] - 2020-06-15 +### Bug Fixes +- **ComponentAnalyzer:** Properly handle sap.ui5/routing ([#463](https://github.com/SAP/ui5-builder/issues/463)) [`717f2ec`](https://github.com/SAP/ui5-builder/commit/717f2ec8e6b04e67966183d25cc0ae59db94f43b) + + + +## [v2.0.3] - 2020-05-19 +### Bug Fixes +- Align JSDoc template and scripts with OpenUI5 1.79 ([#460](https://github.com/SAP/ui5-builder/issues/460)) [`c868fa0`](https://github.com/SAP/ui5-builder/commit/c868fa0d0a4c46d6c3098785a23fee3b7097cf02) +- **manifestBundler:** Add support for i18n object configuration ([#458](https://github.com/SAP/ui5-builder/issues/458)) [`85c4e19`](https://github.com/SAP/ui5-builder/commit/85c4e1958adf407b0dc2f7d4b324e9de354ab670) + + + +## [v2.0.2] - 2020-05-14 + + +## [v2.0.1] - 2020-04-30 +### Bug Fixes +- Namespaces in API Reference (JSDoc) [`b2a9a10`](https://github.com/SAP/ui5-builder/commit/b2a9a10dfee0ab40ce47eb4fb28666f6ea1f2360) + + + +## [v2.0.0] - 2020-03-31 +### Breaking Changes +- Make namespace mandatory for application and library projects ([#430](https://github.com/SAP/ui5-builder/issues/430)) [`ee96c00`](https://github.com/SAP/ui5-builder/commit/ee96c00d762ce24bba39f6c947997fcbb79efaae) +- Require Node.js >= 10 [`5451765`](https://github.com/SAP/ui5-builder/commit/5451765f648ecfe2c057cc2feed2c8fb7e98ef00) +- **LibraryFormatter:** Ignore manifest.json of nested apps [`846e929`](https://github.com/SAP/ui5-builder/commit/846e9290ef29aadc1ad18203003983181cd9c23a) + +### Dependency Updates +- Bump globby from 10.0.2 to 11.0.0 ([#399](https://github.com/SAP/ui5-builder/issues/399)) [`29efbbd`](https://github.com/SAP/ui5-builder/commit/29efbbd8c5d8bf0aca19e75b08f7b3d6f89e8556) + +### Features +- **buildThemes:** Add filtering for available themes ([#419](https://github.com/SAP/ui5-builder/issues/419)) [`848c503`](https://github.com/SAP/ui5-builder/commit/848c5032e98d229a655ddd17f07e252b57838f29) + +### BREAKING CHANGE + +If a library contains both, a manifest.json and .library file, they must +either be located in the same directory or the manifest.json is ignored. +In cases where the manifest.json is located on a higher level or +different directory on the same level than a .library file, an exception +is thrown. + +UI5 Project must be able to determine the project's namespace, +otherwise an error is thrown. + +Support for older Node.js releases has been dropped. +Only Node.js v10 or higher is supported. + + + +## [v1.10.1] - 2020-02-24 +### Bug Fixes +- **ApplicationBuilder:** Fix pattern to glob for .library files [`032d9a9`](https://github.com/SAP/ui5-builder/commit/032d9a974373ffc504fc65b46befe523eb3e4c7d) + + + +## [v1.10.0] - 2020-02-10 +### Bug Fixes +- Ensure proper handling of multi-byte characters in streams ([#411](https://github.com/SAP/ui5-builder/issues/411)) [`e906ec0`](https://github.com/SAP/ui5-builder/commit/e906ec0c3c3eb9fef874f2b7666c692915a496c6) +- **Bundling:** Dynamic preload calls should not emit warnings [`4d22b37`](https://github.com/SAP/ui5-builder/commit/4d22b37852ec130fb3198476e4a6225a47e2b657) + +### Features +- Add experimental CSS variables and skeleton build ([#393](https://github.com/SAP/ui5-builder/issues/393)) [`df8c39b`](https://github.com/SAP/ui5-builder/commit/df8c39b3f5a69086662b6f92c32e1364c1a93903) + + + +## [v1.9.0] - 2020-01-13 +### Bug Fixes +- Use 'defaultFileTypes' from bundle configuration ([#385](https://github.com/SAP/ui5-builder/issues/385)) [`c21e13e`](https://github.com/SAP/ui5-builder/commit/c21e13ea2d7f629b1f91b9acf625989f396c6b4f) +- Detect dynamic dependencies also when newer APIs are used ([#391](https://github.com/SAP/ui5-builder/issues/391)) [`ed1cc9d`](https://github.com/SAP/ui5-builder/commit/ed1cc9d45e517b3b38815483cc60fa7182ffd067) + +### Features +- Add new theme-library type ([#285](https://github.com/SAP/ui5-builder/issues/285)) [`a59287b`](https://github.com/SAP/ui5-builder/commit/a59287b670e956ef29ffe10bbbe1c3506ea3b330) +- **AbstractBuilder:** Allow adding custom tasks for types that have no standard tasks [`654450d`](https://github.com/SAP/ui5-builder/commit/654450df07c22bd1930c014f8b3d6904df8248e9) + + + +## [v1.8.0] - 2019-12-16 +### Features +- Add included/excludedDependencies parameter ([#380](https://github.com/SAP/ui5-builder/issues/380)) [`d6ac24a`](https://github.com/SAP/ui5-builder/commit/d6ac24ab76445568afab3fce9c813a0d5c4c4331) + + + +## [v1.7.1] - 2019-11-18 +### Dependency Updates +- Bump less-openui5 from 0.7.0 to 0.8.0 [`11101d4`](https://github.com/SAP/ui5-builder/commit/11101d4090718f6bee9f6b4851e05b1e1f33d57b) + + + +## [v1.7.0] - 2019-11-07 +### Bug Fixes +- **JSDoc:** Use the rel="noopener" attribute for external links. ([#361](https://github.com/SAP/ui5-builder/issues/361)) [`c702104`](https://github.com/SAP/ui5-builder/commit/c7021046af2ac66aaef8db3841192da8a254d304) + +### Dependency Updates +- Bump less-openui5 from 0.6.0 to 0.7.0 [`fdb0241`](https://github.com/SAP/ui5-builder/commit/fdb0241faec60062b1da52cc296dc343507fb802) + +### Features +- **buildThemes:** Add "compress" option ([#363](https://github.com/SAP/ui5-builder/issues/363)) [`3a0cf6a`](https://github.com/SAP/ui5-builder/commit/3a0cf6aa990a48830d3c22dac285036a290534d8) +- **flexChangesBundler:** Add flexibility-bundle.json ([#353](https://github.com/SAP/ui5-builder/issues/353)) [`cecc97d`](https://github.com/SAP/ui5-builder/commit/cecc97dd626268da2d2c707c5e0a6fabbfc561b6) + + + +## [v1.6.1] - 2019-10-24 +### Bug Fixes +- **jsdoc:** Adopt version range to micro releases ([#357](https://github.com/SAP/ui5-builder/issues/357)) [`619b959`](https://github.com/SAP/ui5-builder/commit/619b959d93441fef1be8c1609ebe5a9eb15759f5) + + + +## [v1.6.0] - 2019-10-24 +### Bug Fixes +- Update JSDoc to 3.6.3 ([#346](https://github.com/SAP/ui5-builder/issues/346)) [`78e2a22`](https://github.com/SAP/ui5-builder/commit/78e2a229f2ae11ca37538a75ac6746ff92af7b84) + +### Features +- **Simple Build Extensibility:** Pass project namespace to custom tasks [`1a167c5`](https://github.com/SAP/ui5-builder/commit/1a167c560ed8cc4e2c28a6c11efb1bf5ed142be9) + ## [v1.5.3] - 2019-10-11 @@ -264,6 +473,32 @@ to load the custom bundle file instead. - Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7) +[v2.4.5]: https://github.com/SAP/ui5-builder/compare/v2.4.4...v2.4.5 +[v2.4.4]: https://github.com/SAP/ui5-builder/compare/v2.4.3...v2.4.4 +[v2.4.3]: https://github.com/SAP/ui5-builder/compare/v2.4.2...v2.4.3 +[v2.4.2]: https://github.com/SAP/ui5-builder/compare/v2.4.1...v2.4.2 +[v2.4.1]: https://github.com/SAP/ui5-builder/compare/v2.4.0...v2.4.1 +[v2.4.0]: https://github.com/SAP/ui5-builder/compare/v2.3.0...v2.4.0 +[v2.3.0]: https://github.com/SAP/ui5-builder/compare/v2.2.1...v2.3.0 +[v2.2.1]: https://github.com/SAP/ui5-builder/compare/v2.2.0...v2.2.1 +[v2.2.0]: https://github.com/SAP/ui5-builder/compare/v2.1.0...v2.2.0 +[v2.1.0]: https://github.com/SAP/ui5-builder/compare/v2.0.7...v2.1.0 +[v2.0.7]: https://github.com/SAP/ui5-builder/compare/v2.0.6...v2.0.7 +[v2.0.6]: https://github.com/SAP/ui5-builder/compare/v2.0.5...v2.0.6 +[v2.0.5]: https://github.com/SAP/ui5-builder/compare/v2.0.4...v2.0.5 +[v2.0.4]: https://github.com/SAP/ui5-builder/compare/v2.0.3...v2.0.4 +[v2.0.3]: https://github.com/SAP/ui5-builder/compare/v2.0.2...v2.0.3 +[v2.0.2]: https://github.com/SAP/ui5-builder/compare/v2.0.1...v2.0.2 +[v2.0.1]: https://github.com/SAP/ui5-builder/compare/v2.0.0...v2.0.1 +[v2.0.0]: https://github.com/SAP/ui5-builder/compare/v1.10.1...v2.0.0 +[v1.10.1]: https://github.com/SAP/ui5-builder/compare/v1.10.0...v1.10.1 +[v1.10.0]: https://github.com/SAP/ui5-builder/compare/v1.9.0...v1.10.0 +[v1.9.0]: https://github.com/SAP/ui5-builder/compare/v1.8.0...v1.9.0 +[v1.8.0]: https://github.com/SAP/ui5-builder/compare/v1.7.1...v1.8.0 +[v1.7.1]: https://github.com/SAP/ui5-builder/compare/v1.7.0...v1.7.1 +[v1.7.0]: https://github.com/SAP/ui5-builder/compare/v1.6.1...v1.7.0 +[v1.6.1]: https://github.com/SAP/ui5-builder/compare/v1.6.0...v1.6.1 +[v1.6.0]: https://github.com/SAP/ui5-builder/compare/v1.5.3...v1.6.0 [v1.5.3]: https://github.com/SAP/ui5-builder/compare/v1.5.2...v1.5.3 [v1.5.2]: https://github.com/SAP/ui5-builder/compare/v1.5.1...v1.5.2 [v1.5.1]: https://github.com/SAP/ui5-builder/compare/v1.5.0...v1.5.1 diff --git a/LICENSE.txt b/LICENSE.txt index d107a1f63..4ed90b952 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,235 +1,208 @@ +Apache License - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Version 2.0, January 2004 - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, +AND DISTRIBUTION 1. Definitions. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ------------------------------------------------------------------------------- -APIs - -This project may include APIs to SAP or third party products or services. The use of these APIs, products and services may be subject to additional agreements. In no event shall the application of the Apache Software License, v.2 to this project grant any rights in or to these APIs, products or services that would alter, expand, be inconsistent with, or supersede any terms of these additional agreements. “API” means application programming interfaces, as well as their respective specifications and implementing code that allows other software products to communicate with or call on SAP or third party products or services (for example, SAP Enterprise Services, BAPIs, Idocs, RFCs and ABAP calls or other user exits) and may be made available through SAP or third party products, SDKs, documentation or other media. - ------------------------------------------------------------------------------- -SUBCOMPONENTS - -This project includes the following subcomponents that are subject to separate license terms. -Your use of these subcomponents is subject to the separate license terms applicable to -each subcomponent. - -Component: deploy.sh -Licensor: Domenic Denicola -Website: https://gist.github.com/domenic/ec8b0fc8ab45f39403dd/e445116166c79d7ac35eb38a5d348d546f3d1620 -License: MIT License - = 2018 - = Domenic Denicola - ------------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------------------------------------------------------------------------------- \ No newline at end of file + + +"License" shall mean the terms and conditions for use, reproduction, and distribution +as defined by Sections 1 through 9 of this document. + + + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + + + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct +or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more +of the outstanding shares, or (iii) beneficial ownership of such entity. + + + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions +granted by this License. + + + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + + + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types. + + + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work (an example is provided in the Appendix +below). + + + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative +Works shall not include works that remain separable from, or merely link (or +bind by name) to the interfaces of, the Work and Derivative Works thereof. + + + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in +the Work by the copyright owner or by an individual or Legal Entity authorized +to submit on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + + + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently incorporated +within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, and distribute +the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, +each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and otherwise +transfer the Work, where such license applies only to those patent claims +licensable by such Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work to which such +Contribution(s) was submitted. If You institute patent litigation against +any entity (including a cross-claim or counterclaim in a lawsuit) alleging +that the Work or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such litigation +is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or +Derivative Works thereof in any medium, with or without modifications, and +in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy +of this License; and + +(b) You must cause any modified files to carry prominent notices stating that +You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source +form of the Work, excluding those notices that do not pertain to any part +of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, +then any Derivative Works that You distribute must include a readable copy +of the attribution notices contained within such NOTICE file, excluding those +notices that do not pertain to any part of the Derivative Works, in at least +one of the following places: within a NOTICE text file distributed as part +of the Derivative Works; within the Source form or documentation, if provided +along with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works +that You distribute, alongside or as an addendum to the NOTICE text from the +Work, provided that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, +or distribution of Your modifications, or for any such Derivative Works as +a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any +Contribution intentionally submitted for inclusion in the Work by You to the +Licensor shall be under the terms and conditions of this License, without +any additional terms or conditions. Notwithstanding the above, nothing herein +shall supersede or modify the terms of any separate license agreement you +may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, +trademarks, service marks, or product names of the Licensor, except as required +for reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to +in writing, Licensor provides the Work (and each Contributor provides its +Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied, including, without limitation, any warranties +or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR +A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness +of using or redistributing the Work and assume any risks associated with Your +exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether +in tort (including negligence), contract, or otherwise, unless required by +applicable law (such as deliberate and grossly negligent acts) or agreed to +in writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of any +character arising as a result of this License or out of the use or inability +to use the Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all other commercial +damages or losses), even if such Contributor has been advised of the possibility +of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work +or Derivative Works thereof, You may choose to offer, and charge a fee for, +acceptance of support, warranty, indemnity, or other liability obligations +and/or rights consistent with this License. However, in accepting such obligations, +You may act only on Your own behalf and on Your sole responsibility, not on +behalf of any other Contributor, and only if You agree to indemnify, defend, +and hold each Contributor harmless for any liability incurred by, or claims +asserted against, such Contributor by reason of your accepting any such warranty +or additional liability. END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in +the appropriate comment syntax for the file format. We also recommend that +a file or class name and description of purpose be included on the same "printed +page" as the copyright notice for easier identification within third-party +archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); + +you may not use this file except in compliance with the License. + +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software + +distributed under the License is distributed on an "AS IS" BASIS, + +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and + +limitations under the License. diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 000000000..4ed90b952 --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,208 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, +AND DISTRIBUTION + + 1. Definitions. + + + +"License" shall mean the terms and conditions for use, reproduction, and distribution +as defined by Sections 1 through 9 of this document. + + + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + + + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct +or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more +of the outstanding shares, or (iii) beneficial ownership of such entity. + + + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions +granted by this License. + + + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + + + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types. + + + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work (an example is provided in the Appendix +below). + + + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative +Works shall not include works that remain separable from, or merely link (or +bind by name) to the interfaces of, the Work and Derivative Works thereof. + + + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in +the Work by the copyright owner or by an individual or Legal Entity authorized +to submit on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + + + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently incorporated +within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, and distribute +the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, +each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and otherwise +transfer the Work, where such license applies only to those patent claims +licensable by such Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work to which such +Contribution(s) was submitted. If You institute patent litigation against +any entity (including a cross-claim or counterclaim in a lawsuit) alleging +that the Work or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such litigation +is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or +Derivative Works thereof in any medium, with or without modifications, and +in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy +of this License; and + +(b) You must cause any modified files to carry prominent notices stating that +You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source +form of the Work, excluding those notices that do not pertain to any part +of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, +then any Derivative Works that You distribute must include a readable copy +of the attribution notices contained within such NOTICE file, excluding those +notices that do not pertain to any part of the Derivative Works, in at least +one of the following places: within a NOTICE text file distributed as part +of the Derivative Works; within the Source form or documentation, if provided +along with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works +that You distribute, alongside or as an addendum to the NOTICE text from the +Work, provided that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, +or distribution of Your modifications, or for any such Derivative Works as +a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any +Contribution intentionally submitted for inclusion in the Work by You to the +Licensor shall be under the terms and conditions of this License, without +any additional terms or conditions. Notwithstanding the above, nothing herein +shall supersede or modify the terms of any separate license agreement you +may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, +trademarks, service marks, or product names of the Licensor, except as required +for reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to +in writing, Licensor provides the Work (and each Contributor provides its +Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied, including, without limitation, any warranties +or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR +A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness +of using or redistributing the Work and assume any risks associated with Your +exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether +in tort (including negligence), contract, or otherwise, unless required by +applicable law (such as deliberate and grossly negligent acts) or agreed to +in writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of any +character arising as a result of this License or out of the use or inability +to use the Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all other commercial +damages or losses), even if such Contributor has been advised of the possibility +of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work +or Derivative Works thereof, You may choose to offer, and charge a fee for, +acceptance of support, warranty, indemnity, or other liability obligations +and/or rights consistent with this License. However, in accepting such obligations, +You may act only on Your own behalf and on Your sole responsibility, not on +behalf of any other Contributor, and only if You agree to indemnify, defend, +and hold each Contributor harmless for any liability incurred by, or claims +asserted against, such Contributor by reason of your accepting any such warranty +or additional liability. END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in +the appropriate comment syntax for the file format. We also recommend that +a file or class name and description of purpose be included on the same "printed +page" as the copyright notice for easier identification within third-party +archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); + +you may not use this file except in compliance with the License. + +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software + +distributed under the License is distributed on an "AS IS" BASIS, + +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and + +limitations under the License. diff --git a/NOTICE.txt b/NOTICE.txt deleted file mode 100644 index efa95dd4c..000000000 --- a/NOTICE.txt +++ /dev/null @@ -1 +0,0 @@ -Copyright (c) 2018-2019 SAP SE or an SAP affiliate company. All rights reserved. diff --git a/README.md b/README.md index 0f87d3e65..14f8f29b9 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,10 @@ > Modules for building UI5 projects > Part of the [UI5 Tooling](https://github.com/SAP/ui5-tooling) +[![REUSE status](https://api.reuse.software/badge/github.com/SAP/ui5-builder)](https://api.reuse.software/info/github.com/SAP/ui5-builder) [![Build Status](https://dev.azure.com/sap/opensource/_apis/build/status/SAP.ui5-builder?branchName=master)](https://dev.azure.com/sap/opensource/_build/latest?definitionId=26&branchName=master) [![npm Package Version](https://badge.fury.io/js/%40ui5%2Fbuilder.svg)](https://www.npmjs.com/package/@ui5/builder) [![Coverage Status](https://coveralls.io/repos/github/SAP/ui5-builder/badge.svg)](https://coveralls.io/github/SAP/ui5-builder) -[![Dependency Status](https://david-dm.org/SAP/ui5-builder/master.svg)](https://david-dm.org/SAP/ui5-builder/master) -[![devDependency Status](https://david-dm.org/SAP/ui5-builder/master/dev-status.svg)](https://david-dm.org/SAP/ui5-builder/master#info=devDependencies) ## Documentation Can be found here: [sap.github.io/ui5-tooling](https://sap.github.io/ui5-tooling/pages/Builder/) @@ -19,8 +18,7 @@ Please check our [Contribution Guidelines](https://github.com/SAP/ui5-tooling/bl ## Support Please follow our [Contribution Guidelines](https://github.com/SAP/ui5-tooling/blob/master/CONTRIBUTING.md#report-an-issue) on how to report an issue. +Please report issues in the main [UI5 Tooling](https://github.com/SAP/ui5-tooling) repository. + ## Release History See [CHANGELOG.md](CHANGELOG.md). - -## License -This project is licensed under the Apache Software License, Version 2.0 except as noted otherwise in the [LICENSE](/LICENSE.txt) file. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a18da2979..fd9cd9987 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -8,21 +8,21 @@ trigger: strategy: matrix: - linux_node_8: - imageName: 'ubuntu-16.04' - node_version: 8.x linux_node_10: - imageName: 'ubuntu-16.04' + imageName: 'ubuntu-18.04' node_version: 10.x + linux_node_lts: + imageName: 'ubuntu-18.04' + node_version: 12.x linux_node_latest: - imageName: 'ubuntu-16.04' - node_version: 11.x + imageName: 'ubuntu-18.04' + node_version: 14.x mac_node_latest: - imageName: 'macos-10.13' - node_version: 11.x + imageName: 'macOS-10.15' + node_version: 14.x windows_node_latest: - imageName: 'vs2017-win2016' - node_version: 11.x + imageName: 'windows-2019' + node_version: 14.x pool: vmImage: $(imageName) @@ -31,20 +31,31 @@ steps: - task: NodeTool@0 inputs: versionSpec: $(node_version) - displayName: 'Install Node.js' + displayName: Install Node.js - script: npm ci + displayName: Install Dependencies + +- script: npm ls + displayName: Check for missing / extraneous Dependencies + - script: npm run test-azure + displayName: Run Tests - task: PublishTestResults@2 + displayName: Publish Test Results condition: succeededOrFailed() inputs: testResultsFormat: 'JUnit' testResultsFiles: '$(System.DefaultWorkingDirectory)/test-results.xml' - task: PublishCodeCoverageResults@1 + displayName: Publish Test Coverage Results condition: succeededOrFailed() inputs: codeCoverageTool: 'cobertura' summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml' +- script: npm run test + displayName: Run Test Natively in Case of Failures + condition: failed() diff --git a/index.js b/index.js index 77f967d03..4ea2a17c2 100644 --- a/index.js +++ b/index.js @@ -3,65 +3,210 @@ * @public */ module.exports = { - builder: require("./lib/builder/builder"), + /** + * @type {import('./lib/builder/builder')} + */ + builder: "./lib/builder/builder", /** * @public - * @see module:@ui5/builder.processors + * @alias module:@ui5/builder.processors * @namespace */ processors: { - flexChangesBundler: require("./lib/processors/bundlers/flexChangesBundler"), - manifestBundler: require("./lib/processors/bundlers/manifestBundler"), - moduleBundler: require("./lib/processors/bundlers/moduleBundler"), - apiIndexGenerator: require("./lib/processors/jsdoc/apiIndexGenerator"), - jsdocGenerator: require("./lib/processors/jsdoc/jsdocGenerator"), - sdkTransformer: require("./lib/processors/jsdoc/sdkTransformer"), - bootstrapHtmlTransformer: require("./lib/processors/bootstrapHtmlTransformer"), - debugFileCreator: require("./lib/processors/debugFileCreator"), - resourceCopier: require("./lib/processors/resourceCopier"), - nonAsciiEscaper: require("./lib/processors/nonAsciiEscaper"), - stringReplacer: require("./lib/processors/stringReplacer"), - themeBuilder: require("./lib/processors/themeBuilder"), - uglifier: require("./lib/processors/uglifier"), - versionInfoGenerator: require("./lib/processors/versionInfoGenerator") + /** + * @type {import('./lib/processors/bundlers/flexChangesBundler')} + */ + flexChangesBundler: "./lib/processors/bundlers/flexChangesBundler", + /** + * @type {import('./lib/processors/bundlers/manifestBundler')} + */ + manifestBundler: "./lib/processors/bundlers/manifestBundler", + /** + * @type {import('./lib/processors/bundlers/moduleBundler')} + */ + moduleBundler: "./lib/processors/bundlers/moduleBundler", + /** + * @type {import('./lib/processors/jsdoc/apiIndexGenerator')} + */ + apiIndexGenerator: "./lib/processors/jsdoc/apiIndexGenerator", + /** + * @type {import('./lib/processors/jsdoc/jsdocGenerator')} + */ + jsdocGenerator: "./lib/processors/jsdoc/jsdocGenerator", + /** + * @type {import('./lib/processors/jsdoc/sdkTransformer')} + */ + sdkTransformer: "./lib/processors/jsdoc/sdkTransformer", + /** + * @type {import('./lib/processors/bootstrapHtmlTransformer')} + */ + bootstrapHtmlTransformer: "./lib/processors/bootstrapHtmlTransformer", + /** + * @type {import('./lib/processors/debugFileCreator')} + */ + debugFileCreator: "./lib/processors/debugFileCreator", + /** + * @type {import('./lib/processors/resourceCopier')} + */ + resourceCopier: "./lib/processors/resourceCopier", + /** + * @type {import('./lib/processors/nonAsciiEscaper')} + */ + nonAsciiEscaper: "./lib/processors/nonAsciiEscaper", + /** + * @type {import('./lib/processors/stringReplacer')} + */ + stringReplacer: "./lib/processors/stringReplacer", + /** + * @type {import('./lib/processors/themeBuilder')} + */ + themeBuilder: "./lib/processors/themeBuilder", + /** + * @type {import('./lib/processors/uglifier')} + */ + uglifier: "./lib/processors/uglifier", + /** + * @type {import('./lib/processors/versionInfoGenerator')} + */ + versionInfoGenerator: "./lib/processors/versionInfoGenerator" }, /** * @public - * @see module:@ui5/builder.tasks + * @alias module:@ui5/builder.tasks * @namespace */ tasks: { - generateComponentPreload: require("./lib/tasks/bundlers/generateComponentPreload"), - generateFlexChangesBundle: require("./lib/tasks/bundlers/generateFlexChangesBundle"), - generateLibraryPreload: require("./lib/tasks/bundlers/generateLibraryPreload"), - generateManifestBundle: require("./lib/tasks/bundlers/generateManifestBundle"), - generateStandaloneAppBundle: require("./lib/tasks/bundlers/generateStandaloneAppBundle"), - generateBundle: require("./lib/tasks/bundlers/generateBundle"), - generateCachebusterInfo: require("./lib/tasks/generateCachebusterInfo"), - buildThemes: require("./lib/tasks/buildThemes"), - createDebugFiles: require("./lib/tasks/createDebugFiles"), - executeJsdocSdkTransformation: require("./lib/tasks/jsdoc/executeJsdocSdkTransformation"), - generateApiIndex: require("./lib/tasks/jsdoc/generateApiIndex"), - generateJsdoc: require("./lib/tasks/jsdoc/generateJsdoc"), - generateVersionInfo: require("./lib/tasks/generateVersionInfo"), - escapeNonAsciiCharacters: require("./lib/tasks/escapeNonAsciiCharacters"), - replaceCopyright: require("./lib/tasks/replaceCopyright"), - replaceVersion: require("./lib/tasks/replaceVersion"), - transformBootstrapHtml: require("./lib/tasks/transformBootstrapHtml"), - uglify: require("./lib/tasks/uglify"), - taskRepository: require("./lib/tasks/taskRepository") + /** + * @type {import('./lib/tasks/bundlers/generateComponentPreload')} + */ + generateComponentPreload: "./lib/tasks/bundlers/generateComponentPreload", + /** + * @type {import('./lib/tasks/bundlers/generateFlexChangesBundle')} + */ + generateFlexChangesBundle: "./lib/tasks/bundlers/generateFlexChangesBundle", + /** + * @type {import('./lib/tasks/bundlers/generateLibraryPreload')} + */ + generateLibraryPreload: "./lib/tasks/bundlers/generateLibraryPreload", + /** + * @type {import('./lib/tasks/bundlers/generateManifestBundle')} + */ + generateManifestBundle: "./lib/tasks/bundlers/generateManifestBundle", + /** + * @type {import('./lib/tasks/bundlers/generateStandaloneAppBundle')} + */ + generateStandaloneAppBundle: "./lib/tasks/bundlers/generateStandaloneAppBundle", + /** + * @type {import('./lib/tasks/bundlers/generateBundle')} + */ + generateBundle: "./lib/tasks/bundlers/generateBundle", + /** + * @type {import('./lib/tasks/generateCachebusterInfo')} + */ + generateCachebusterInfo: "./lib/tasks/generateCachebusterInfo", + /** + * @type {import('./lib/tasks/buildThemes')} + */ + buildThemes: "./lib/tasks/buildThemes", + /** + * @type {import('./lib/tasks/createDebugFiles')} + */ + createDebugFiles: "./lib/tasks/createDebugFiles", + /** + * @type {import('./lib/tasks/jsdoc/executeJsdocSdkTransformation')} + */ + executeJsdocSdkTransformation: "./lib/tasks/jsdoc/executeJsdocSdkTransformation", + /** + * @type {import('./lib/tasks/jsdoc/generateApiIndex')} + */ + generateApiIndex: "./lib/tasks/jsdoc/generateApiIndex", + /** + * @type {import('./lib/tasks/jsdoc/generateJsdoc')} + */ + generateJsdoc: "./lib/tasks/jsdoc/generateJsdoc", + /** + * @type {import('./lib/tasks/generateVersionInfo')} + */ + generateVersionInfo: "./lib/tasks/generateVersionInfo", + /** + * @type {import('./lib/tasks/escapeNonAsciiCharacters')} + */ + escapeNonAsciiCharacters: "./lib/tasks/escapeNonAsciiCharacters", + /** + * @type {import('./lib/tasks/replaceCopyright')} + */ + replaceCopyright: "./lib/tasks/replaceCopyright", + /** + * @type {import('./lib/tasks/replaceVersion')} + */ + replaceVersion: "./lib/tasks/replaceVersion", + /** + * @type {import('./lib/tasks/transformBootstrapHtml')} + */ + transformBootstrapHtml: "./lib/tasks/transformBootstrapHtml", + /** + * @type {import('./lib/tasks/uglify')} + */ + uglify: "./lib/tasks/uglify", + /** + * @type {import('./lib/tasks/taskRepository')} + */ + taskRepository: "./lib/tasks/taskRepository", + /** + * @type {import('./lib/tasks/TaskUtil')} + */ + TaskUtil: "./lib/tasks/TaskUtil" }, /** * @private - * @see module:@ui5/builder.types + * @alias module:@ui5/builder.types * @namespace */ types: { - AbstractBuilder: require("./lib/types/AbstractBuilder"), - AbstractFormatter: require("./lib/types/AbstractFormatter"), - application: require("./lib/types/application/applicationType"), - library: require("./lib/types/library/libraryType"), - typeRepository: require("./lib/types/typeRepository") + /** + * @type {typeof import('./lib/types/AbstractBuilder')} + */ + AbstractBuilder: "./lib/types/AbstractBuilder", + /** + * @type {typeof import('./lib/types/AbstractFormatter')} + */ + AbstractFormatter: "./lib/types/AbstractFormatter", + /** + * @type {import('./lib/types/application/applicationType')} + */ + application: "./lib/types/application/applicationType", + /** + * @type {import('./lib/types/library/libraryType')} + */ + library: "./lib/types/library/libraryType", + /** + * @type {import('./lib/types/themeLibrary/themeLibraryType')} + */ + themeLibrary: "./lib/types/themeLibrary/themeLibraryType", + /** + * @type {import('./lib/types/module/moduleType')} + */ + module: "./lib/types/module/moduleType", + /** + * @type {import('./lib/types/typeRepository')} + */ + typeRepository: "./lib/types/typeRepository" } }; +function exportModules(exportRoot, modulePaths) { + for (const moduleName of Object.keys(modulePaths)) { + if (typeof modulePaths[moduleName] === "object") { + exportRoot[moduleName] = {}; + exportModules(exportRoot[moduleName], modulePaths[moduleName]); + } else { + Object.defineProperty(exportRoot, moduleName, { + get() { + return require(modulePaths[moduleName]); + } + }); + } + } +} + +exportModules(module.exports, JSON.parse(JSON.stringify(module.exports))); diff --git a/jsdoc-plugin.js b/jsdoc-plugin.js new file mode 100644 index 000000000..bf94fbc6e --- /dev/null +++ b/jsdoc-plugin.js @@ -0,0 +1,13 @@ +/* + * Removes JSDoc comments with TypeScript import() declarations (used in index.js) + */ + +const IMPORT_PATTERN = /{(?:typeof )?import\(["'][^"']*["']\)[ .|}><,)=#\n]/; + +exports.handlers = { + jsdocCommentFound: function(e) { + if (IMPORT_PATTERN.test(e.comment)) { + e.comment = ""; + } + } +}; diff --git a/jsdoc.json b/jsdoc.json index 7552fc449..2079cf56d 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -1,61 +1,63 @@ { - "tags": { - "allowUnknownTags": false - }, - "source": { - "include": ["README.md", "index.js"], - "exclude": ["lib/lbt/utils/JSTokenizer.js"], - "includePattern": ".+\\.js$", - "excludePattern": "(node_modules(\\\\|/))" - }, - "plugins": [], - "opts": { - "template": "node_modules/docdash/", - "encoding": "utf8", - "destination": "jsdocs/", - "recurse": true, - "verbose": true, - "access": "public" - }, - "templates": { - "cleverLinks": false, - "monospaceLinks": false, - "default": { - "useLongnameInNav": true - } - }, - "openGraph": { - "title": "UI5 Tooling - API Reference", - "type": "website", - "image": "https://sap.github.io/ui5-tooling/docs/images/UI5_logo_wide.png", - "site_name": "UI5 Tooling - API Reference", - "url": "https://sap.github.io/ui5-tooling/" - }, - "docdash": { - "sectionOrder": [ - "Modules", - "Namespaces", - "Classes", - "Externals", - "Events", - "Mixins", - "Tutorials", - "Interfaces" - ], - "meta": { - "title": "UI5 Tooling - API Reference - UI5 Builder", - "description": "UI5 Tooling - API Reference - UI5 Builder", - "keyword": "openui5 sapui5 ui5 build development tool api reference" - }, - "search": true, - "wrap": true, - "menu": { - "GitHub": { - "href": "https://github.com/SAP/ui5-builder", - "target": "_blank", - "class": "menu-item", - "id": "github_link" - } - } - } + "tags": { + "allowUnknownTags": false + }, + "source": { + "include": ["README.md", "index.js"], + "exclude": ["lib/lbt/utils/JSTokenizer.js"], + "includePattern": ".+\\.js$", + "excludePattern": "(node_modules(\\\\|/))" + }, + "plugins": [ + "./jsdoc-plugin" + ], + "opts": { + "template": "node_modules/docdash/", + "encoding": "utf8", + "destination": "jsdocs/", + "recurse": true, + "verbose": true, + "access": "public" + }, + "templates": { + "cleverLinks": false, + "monospaceLinks": false, + "default": { + "useLongnameInNav": true + } + }, + "openGraph": { + "title": "UI5 Tooling - API Reference", + "type": "website", + "image": "https://sap.github.io/ui5-tooling/docs/images/UI5_logo_wide.png", + "site_name": "UI5 Tooling - API Reference", + "url": "https://sap.github.io/ui5-tooling/" + }, + "docdash": { + "sectionOrder": [ + "Modules", + "Namespaces", + "Classes", + "Externals", + "Events", + "Mixins", + "Tutorials", + "Interfaces" + ], + "meta": { + "title": "UI5 Tooling - API Reference - UI5 Builder", + "description": "UI5 Tooling - API Reference - UI5 Builder", + "keyword": "openui5 sapui5 ui5 build development tool api reference" + }, + "search": true, + "wrap": true, + "menu": { + "GitHub": { + "href": "https://github.com/SAP/ui5-builder", + "target": "_blank", + "class": "menu-item", + "id": "github_link" + } + } + } } diff --git a/lib/builder/BuildContext.js b/lib/builder/BuildContext.js index 05a29c672..0f61271a7 100644 --- a/lib/builder/BuildContext.js +++ b/lib/builder/BuildContext.js @@ -1,3 +1,5 @@ +const ProjectBuildContext = require("./ProjectBuildContext"); + /** * Context of a build process * @@ -5,10 +7,18 @@ * @memberof module:@ui5/builder.builder */ class BuildContext { - constructor() { + constructor({rootProject}) { + if (!rootProject) { + throw new Error(`Missing parameter 'rootProject'`); + } + this.rootProject = rootProject; this.projectBuildContexts = []; } + getRootProject() { + return this.rootProject; + } + createProjectContext({project, resources}) { const projectBuildContext = new ProjectBuildContext({ buildContext: this, @@ -26,33 +36,4 @@ class BuildContext { } } - -/** - * Build context of a single project. Always part of an overall - * [Build Context]{@link module:@ui5/builder.builder.BuildContext} - * - * @private - * @memberof module:@ui5/builder.builder - */ -class ProjectBuildContext { - constructor({buildContext, project, resources}) { - // this.buildContext = buildContext; - // this.project = project; - // this.resources = resources; - this.queues = { - cleanup: [] - }; - } - - registerCleanupTask(callback) { - this.queues.cleanup.push(callback); - } - - async executeCleanupTasks() { - await Promise.all(this.queues.cleanup.map((callback) => { - return callback(); - })); - } -} - module.exports = BuildContext; diff --git a/lib/builder/ProjectBuildContext.js b/lib/builder/ProjectBuildContext.js new file mode 100644 index 000000000..2ff81da50 --- /dev/null +++ b/lib/builder/ProjectBuildContext.js @@ -0,0 +1,53 @@ +const ResourceTagCollection = require("@ui5/fs").ResourceTagCollection; + +const STANDARD_TAGS = Object.freeze({ + OmitFromBuildResult: "ui5:OmitFromBuildResult", + IsBundle: "ui5:IsBundle" +}); + +/** + * Build context of a single project. Always part of an overall + * [Build Context]{@link module:@ui5/builder.builder.BuildContext} + * + * @private + * @memberof module:@ui5/builder.builder + */ +class ProjectBuildContext { + constructor({buildContext, project, resources}) { + if (!buildContext || !project || !resources) { + throw new Error(`One or more mandatory parameters are missing`); + } + this._buildContext = buildContext; + this._project = project; + // this.resources = resources; + this.queues = { + cleanup: [] + }; + + this.STANDARD_TAGS = STANDARD_TAGS; + + this._resourceTagCollection = new ResourceTagCollection({ + allowedTags: Object.values(this.STANDARD_TAGS) + }); + } + + isRootProject() { + return this._project === this._buildContext.getRootProject(); + } + + registerCleanupTask(callback) { + this.queues.cleanup.push(callback); + } + + async executeCleanupTasks() { + await Promise.all(this.queues.cleanup.map((callback) => { + return callback(); + })); + } + + getResourceTagCollection() { + return this._resourceTagCollection; + } +} + +module.exports = ProjectBuildContext; diff --git a/lib/builder/builder.js b/lib/builder/builder.js index 5392cdfd1..de070647b 100644 --- a/lib/builder/builder.js +++ b/lib/builder/builder.js @@ -7,7 +7,6 @@ const typeRepository = require("../types/typeRepository"); const taskRepository = require("../tasks/taskRepository"); const BuildContext = require("./BuildContext"); -const definedTasks = taskRepository.getAllTasks(); // Set of tasks for development const devTasks = [ @@ -37,16 +36,18 @@ function getElapsedTime(startTime) { * Tasks can be enabled or disabled. The wildcard * is also supported and affects all tasks. * * @private - * @param {Object} parameters + * @param {object} parameters * @param {boolean} parameters.dev Sets development mode, which only runs essential tasks - * @param {boolean} parameters.selfContained True if a the build should be self-contained or false for prelead build bundles + * @param {boolean} parameters.selfContained + * True if a the build should be self-contained or false for prelead build bundles * @param {boolean} parameters.jsdoc True if a JSDoc build should be executed * @param {Array} parameters.includedTasks Task list to be included from build * @param {Array} parameters.excludedTasks Task list to be excluded from build * @returns {Array} Return a task list for the builder */ function composeTaskList({dev, selfContained, jsdoc, includedTasks, excludedTasks}) { - let selectedTasks = Object.keys(definedTasks).reduce((list, key) => { + const definedTasks = taskRepository.getAllTaskNames(); + let selectedTasks = definedTasks.reduce((list, key) => { list[key] = true; return list; }, {}); @@ -60,6 +61,11 @@ function composeTaskList({dev, selfContained, jsdoc, includedTasks, excludedTask selectedTasks.generateCachebusterInfo = false; selectedTasks.generateApiIndex = false; + // Disable generateResourcesJson due to performance. + // When executed it analyzes each module's AST and therefore + // takes up much time (~10% more) + selectedTasks.generateResourcesJson = false; + if (selfContained) { // No preloads, bundle only selectedTasks.generateComponentPreload = false; @@ -155,10 +161,8 @@ function registerCleanupSigHooks(buildContext) { "SIGBREAK": createListener(128 + 21) }; - for (const signal in processSignals) { - if (processSignals.hasOwnProperty(signal)) { - process.on(signal, processSignals[signal]); - } + for (const signal of Object.keys(processSignals)) { + process.on(signal, processSignals[signal]); } // == TO BE DISCUSSED: Also cleanup for unhandled rejections and exceptions? @@ -181,10 +185,8 @@ function registerCleanupSigHooks(buildContext) { } function deregisterCleanupSigHooks(signals) { - for (const signal in signals) { - if (signals.hasOwnProperty(signal)) { - process.removeListener(signal, signals[signal]); - } + for (const signal of Object.keys(signals)) { + process.removeListener(signal, signals[signal]); } } @@ -196,28 +198,35 @@ function deregisterCleanupSigHooks(signals) { * @alias module:@ui5/builder.builder */ module.exports = { - tasks: definedTasks, - /** * Configures the project build and starts it. * * @public - * @param {Object} parameters Parameters - * @param {Object} parameters.tree Dependency tree + * @param {object} parameters Parameters + * @param {object} parameters.tree Project tree as generated by the + * [@ui5/project.normalizer]{@link module:@ui5/project.normalizer} * @param {string} parameters.destPath Target path * @param {boolean} [parameters.cleanDest=false] Decides whether project should clean the target path before build * @param {boolean} [parameters.buildDependencies=false] Decides whether project dependencies are built as well - * @param {boolean} [parameters.dev=false] Decides whether a development build should be activated (skips non-essential and time-intensive tasks) + * @param {Array.} [parameters.includedDependencies=[]] + * List of build dependencies to be included if buildDependencies is true + * @param {Array.} [parameters.excludedDependencies=[]] + * List of build dependencies to be excluded if buildDependencies is true. + * If the wildcard '*' is provided, only the included dependencies will be built. + * @param {boolean} [parameters.dev=false] + * Decides whether a development build should be activated (skips non-essential and time-intensive tasks) * @param {boolean} [parameters.selfContained=false] Flag to activate self contained build * @param {boolean} [parameters.jsdoc=false] Flag to activate JSDoc build - * @param {Array} [parameters.includedTasks=[]] List of tasks to be included - * @param {Array} [parameters.excludedTasks=[]] List of tasks to be excluded. If the wildcard '*' is provided, only the included tasks will be executed. - * @param {Array} [parameters.devExcludeProject=[]] List of projects to be excluded from development build + * @param {Array.} [parameters.includedTasks=[]] List of tasks to be included + * @param {Array.} [parameters.excludedTasks=[]] List of tasks to be excluded. + * If the wildcard '*' is provided, only the included tasks will be executed. + * @param {Array.} [parameters.devExcludeProject=[]] List of projects to be excluded from development build * @returns {Promise} Promise resolving to undefined once build has finished */ async build({ tree, destPath, cleanDest = false, - buildDependencies = false, dev = false, selfContained = false, jsdoc = false, + buildDependencies = false, includedDependencies = [], excludedDependencies = [], + dev = false, selfContained = false, jsdoc = false, includedTasks = [], excludedTasks = [], devExcludeProject = [] }) { const startTime = process.hrtime(); @@ -232,16 +241,35 @@ module.exports = { virBasePath: "/" }); - const buildContext = new BuildContext(); + const buildContext = new BuildContext({rootProject: tree}); const cleanupSigHooks = registerCleanupSigHooks(buildContext); const projects = {}; // Unique project index to prevent building the same project multiple times const projectWriters = {}; // Collection of memory adapters of already built libraries + function projectFilter(project) { + function projectMatchesAny(deps) { + return deps.some((dep) => dep instanceof RegExp ? + dep.test(project.metadata.name) : dep === project.metadata.name); + } + + // if everything is included, this overrules exclude lists + if (includedDependencies.includes("*")) return true; + let test = !excludedDependencies.includes("*"); // exclude everything? + + if (test && projectMatchesAny(excludedDependencies)) { + test = false; + } + if (!test && projectMatchesAny(includedDependencies)) { + test = true; + } + + return test; + } const projectCountMarker = {}; function projectCount(project, count = 0) { if (buildDependencies) { - count = project.dependencies.reduce((depCount, depProject) => { + count = project.dependencies.filter(projectFilter).reduce((depCount, depProject) => { return projectCount(depProject, depCount); }, count); } @@ -251,21 +279,22 @@ module.exports = { } return count; } - const iProjectCount = projectCount(tree); - const buildLogger = log.createTaskLogger("🛠 ", iProjectCount); + const buildLogger = log.createTaskLogger("🛠 ", projectCount(tree)); function buildProject(project) { let depPromise; let projectTasks = selectedTasks; + + // Build dependencies in sequence as it is far easier to detect issues and reduces + // side effects or other issues such as too many open files if (buildDependencies) { - // Build dependencies in sequence as it is far easier to detect issues and reduces - // side effects or other issues such as too many open files - depPromise = project.dependencies.reduce(function(p, depProject) { + depPromise = project.dependencies.filter(projectFilter).reduce(function(p, depProject) { return p.then(() => buildProject(depProject)); }, Promise.resolve()); } else { depPromise = Promise.resolve(); } + // Build the project after all dependencies have been built return depPromise.then(() => { if (projects[project.metadata.name]) { @@ -306,13 +335,18 @@ module.exports = { }); const projectContext = buildContext.createProjectContext({ - // project, // TODO 2.0: Add project facade object/instance here + project, // TODO 2.0: Add project facade object/instance here resources: { workspace, dependencies: resourceCollections.dependencies } }); + const TaskUtil = require("../tasks/TaskUtil"); + const taskUtil = new TaskUtil({ + projectBuildContext: projectContext + }); + if (dev && devExcludeProject.indexOf(project.metadata.name) !== -1) { projectTasks = composeTaskList({dev: false, selfContained, includedTasks, excludedTasks}); } @@ -325,14 +359,21 @@ module.exports = { tasks: projectTasks, project, parentLogger: log, - buildContext: projectContext + taskUtil }).then(() => { log.verbose("Finished building project %s. Writing out files...", project.metadata.name); buildLogger.completeWork(1); return workspace.byGlob("/**/*.*").then((resources) => { + const tagCollection = projectContext.getResourceTagCollection(); return Promise.all(resources.map((resource) => { - if (project === tree && project.type === "application" && project.metadata.namespace) { + if (tagCollection.getTag(resource, projectContext.STANDARD_TAGS.OmitFromBuildResult)) { + log.verbose(`Skipping write of resource tagged as "OmitFromBuildResult": ` + + resource.getPath()); + return; // Skip target write for this resource + } + if (projectContext.isRootProject() && project.type === "application" && + project.metadata.namespace) { // Root-application projects only: Remove namespace prefix if given resource.setPath(resource.getPath().replace( new RegExp(`^/resources/${project.metadata.namespace}`), "")); diff --git a/lib/lbt/analyzer/ComponentAnalyzer.js b/lib/lbt/analyzer/ComponentAnalyzer.js index 5e22bdcdd..fb2f47194 100644 --- a/lib/lbt/analyzer/ComponentAnalyzer.js +++ b/lib/lbt/analyzer/ComponentAnalyzer.js @@ -35,6 +35,7 @@ function each(obj, fn) { /** * Analyzes the manifest for a Component.js to find more dependencies. + * * @since 1.47.0 * @private */ @@ -59,7 +60,7 @@ class ComponentAnalyzer { log.verbose("No manifest found for '%s', skipping analysis", resource.name); } } catch (err) { - log.error("an error occurred while analyzing component %s (ignored)", resource.name, err); + log.error("an error occurred while analyzing component %s (ignored)", resource.name, err.stack); } return info; @@ -69,7 +70,7 @@ class ComponentAnalyzer { * Evaluates a manifest after it has been read and parsed * and adds any newly found dependencies to the given info object. * - * @param {Object} manifest JSON with app descriptor structure + * @param {object} manifest JSON with app descriptor structure * @param {ModuleInfo} info ModuleInfo object that should be enriched * @returns {ModuleInfo} ModuleInfo object that should be enriched * @private @@ -187,20 +188,19 @@ class ComponentAnalyzer { info.addDependency(viewsModule); } - for (const targetName in routing.targets) { - if (!routing.targets.hasOwnProperty(targetName)) { - continue; - } - const target = routing.targets[targetName]; - if (target && target.viewName) { - // merge target config with default config - const config = Object.assign({}, routing.config, target); - const module = ModuleName.fromUI5LegacyName( - (config.viewPath ? config.viewPath + "." : "") + - config.viewName, ".view." + config.viewType.toLowerCase() ); - log.verbose("converting routing target '%s' to view dependency '%s'", targetName, module); - // TODO make this a conditional dependency, depending on the route pattern? - info.addDependency(module); + if (routing.targets) { + for (const targetName of Object.keys(routing.targets)) { + const target = routing.targets[targetName]; + if (target && target.viewName) { + // merge target config with default config + const config = Object.assign({}, routing.config, target); + const module = ModuleName.fromUI5LegacyName( + (config.viewPath ? config.viewPath + "." : "") + + config.viewName, ".view." + config.viewType.toLowerCase() ); + log.verbose("converting routing target '%s' to view dependency '%s'", targetName, module); + // TODO make this a conditional dependency, depending on the route pattern? + info.addDependency(module); + } } } } diff --git a/lib/lbt/analyzer/FioriElementsAnalyzer.js b/lib/lbt/analyzer/FioriElementsAnalyzer.js index 597e1bfad..e4cf9ebb6 100644 --- a/lib/lbt/analyzer/FioriElementsAnalyzer.js +++ b/lib/lbt/analyzer/FioriElementsAnalyzer.js @@ -80,6 +80,7 @@ const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"]; /** * Analyzes the manifest for a Fiori Elements application (next to its Component.js) to find more dependencies. + * * @private */ class FioriElementsAnalyzer { @@ -113,7 +114,7 @@ class FioriElementsAnalyzer { * Evaluates a manifest after it has been read and parsed * and adds any newly found dependencies to the given info object. * - * @param {Object} manifest JSON with app descriptor structure + * @param {object} manifest JSON with app descriptor structure * @param {ModuleInfo} info ModuleInfo object that should be enriched * @returns {ModuleInfo} ModuleInfo object that should be enriched * @private @@ -166,10 +167,10 @@ class FioriElementsAnalyzer { // console.log("local name for TemplateAssembler: %s", TA); if ( TA && defineCall.factory ) { defineCall.factory.body.body.forEach( (stmt) => { - if ( stmt.type === Syntax.ReturnStatement - && isMethodCall(stmt.argument, [TA, "getTemplateComponent"]) - && stmt.argument.arguments.length > 2 - && stmt.argument.arguments[2].type === "ObjectExpression" ) { + if ( stmt.type === Syntax.ReturnStatement && + isMethodCall(stmt.argument, [TA, "getTemplateComponent"]) && + stmt.argument.arguments.length > 2 && + stmt.argument.arguments[2].type === "ObjectExpression" ) { templateName = this._analyzeTemplateClassDefinition(stmt.argument.arguments[2]) || templateName; } }); diff --git a/lib/lbt/analyzer/JSModuleAnalyzer.js b/lib/lbt/analyzer/JSModuleAnalyzer.js index 4ade9d323..e6dc31957 100644 --- a/lib/lbt/analyzer/JSModuleAnalyzer.js +++ b/lib/lbt/analyzer/JSModuleAnalyzer.js @@ -239,6 +239,13 @@ function getDocumentation(node) { * @private */ class JSModuleAnalyzer { + /** + * Analyzes the JS AST + * + * @param {object} ast js ast + * @param {string} defaultName default name + * @param {ModuleInfo} info module info + */ analyze(ast, defaultName, info) { let mainModuleFound = false; /** @@ -260,6 +267,20 @@ class JSModuleAnalyzer { */ let nModuleDeclarations = 0; + /** + * Whether or not this is a UI5 module + * + * When in the non-conditional module execution there is a call to: + *
    + *
  • sap.ui.define call
  • + *
  • jQuery.sap.declare call
  • + *
+ * this value is true + * + * @type {boolean} + */ + let bIsUi5Module = false; + // first analyze the whole AST... visit(ast, false); @@ -270,11 +291,11 @@ class JSModuleAnalyzer { if ( comment.value.startsWith("@ui5-bundle-raw-include ") ) { const subModule = comment.value.slice("@ui5-bundle-raw-include ".length); info.addSubModule(subModule); - log.debug(`bundle include directive ${subModule}`); + log.verbose(`bundle include directive ${subModule}`); } else if ( comment.value.startsWith("@ui5-bundle ") ) { const bundleName = comment.value.slice("@ui5-bundle ".length); setMainModuleInfo(bundleName, null); - log.debug(`bundle name directive ${bundleName}`); + log.verbose(`bundle name directive ${bundleName}`); } else { log.warn(`unrecognized bundle directive ${comment.value}`); } @@ -307,7 +328,7 @@ class JSModuleAnalyzer { info.addImplicitDependency(UI5ClientConstants.MODULE__UI5LOADER_AUTOCONFIG); } - if ( nModuleDeclarations === 0 && info.dependencies.length === 0 && info.subModules.length === 0 ) { + if ( !bIsUi5Module ) { // when there are no indicators for module APIs, mark the module as 'raw' module info.rawModule = true; } @@ -320,7 +341,6 @@ class JSModuleAnalyzer { // console.log(info.name, "exposed globals", info.exposedGlobals, "ignoredGlobals", info.ignoredGlobals); } - return; // hoisted functions function setMainModuleInfo(name, description) { @@ -353,9 +373,10 @@ class JSModuleAnalyzer { // recognized a call to jQuery.sap.declare() nModuleDeclarations++; info.setFormat(ModuleFormat.UI5_LEGACY); + bIsUi5Module = true; onDeclare(node); - } else if ( !conditional - && (isMethodCall(node, CALL_SAP_UI_DEFINE) || isMethodCall(node, CALL_AMD_DEFINE)) ) { + } else if ( !conditional && + (isMethodCall(node, CALL_SAP_UI_DEFINE) || isMethodCall(node, CALL_AMD_DEFINE)) ) { // recognized a call to define() or sap.ui.define() // console.log("**** recognized a call to sap.ui.define"); nModuleDeclarations++; @@ -364,6 +385,7 @@ class JSModuleAnalyzer { } else { info.setFormat(ModuleFormat.AMD); } + bIsUi5Module = true; onDefine(node); const args = node.arguments; @@ -380,8 +402,24 @@ class JSModuleAnalyzer { } } else if ( isMethodCall(node, CALL_REQUIRE_PREDEFINE) || isMethodCall(node, CALL_SAP_UI_PREDEFINE) ) { // recognized a call to require.predefine() or sap.ui.predefine() + if (!conditional) { + bIsUi5Module = true; + } info.setFormat(ModuleFormat.UI5_DEFINE); - onSapUiPredefine(node); + onSapUiPredefine(node, conditional); + + const args = node.arguments; + let iArg = 0; + if ( iArg < args.length && isString(args[iArg]) ) { + iArg++; + } + if ( iArg < args.length && args[iArg].type == Syntax.ArrayExpression ) { + iArg++; + } + if ( iArg < args.length && isCallableExpression(args[iArg]) ) { + // unconditionally execute the factory function + visit(args[iArg].body, conditional); + } } else if ( isMethodCall(node, CALL_SAP_UI_REQUIRE) || isMethodCall(node, CALL_AMD_REQUIRE) ) { // recognized a call to require() or sap.ui.require() if ( isMethodCall(node, CALL_SAP_UI_REQUIRE) ) { @@ -404,6 +442,7 @@ class JSModuleAnalyzer { } else if ( isMethodCall(node, CALL_REQUIRE_SYNC) || isMethodCall(node, CALL_SAP_UI_REQUIRE_SYNC) ) { // recognizes a call to sap.ui.requireSync info.setFormat(ModuleFormat.UI5_DEFINE); + onSapUiRequireSync(node, conditional); } else if ( isMethodCall(node, CALL_JQUERY_SAP_REQUIRE) ) { // recognizes a call to jQuery.sap.require @@ -411,10 +450,16 @@ class JSModuleAnalyzer { onJQuerySapRequire(node, conditional); } else if ( isMethodCall(node, CALL_JQUERY_SAP_REGISTER_PRELOADED_MODULES) ) { // recognizes a call to jQuery.sap.registerPreloadedModules + if (!conditional) { + bIsUi5Module = true; + } info.setFormat(ModuleFormat.UI5_LEGACY); onRegisterPreloadedModules(node, /* evoSyntax= */ false); } else if ( isMethodCall(node, CALL_SAP_UI_REQUIRE_PRELOAD) ) { // recognizes a call to sap.ui.require.preload + if (!conditional) { + bIsUi5Module = true; + } info.setFormat(ModuleFormat.UI5_DEFINE); onRegisterPreloadedModules(node, /* evoSyntax= */ true); } else if ( isCallableExpression(node.callee) ) { @@ -437,9 +482,9 @@ class JSModuleAnalyzer { // } // required for the analysis of files that have been build with the // embedding merge writer (e.g. sap-ui-core-all.js) - if ( node.test.type == Syntax.UnaryExpression - && node.test.operator === "!" - && isMethodCall(node.test.argument, CALL_JQUERY_SAP_IS_DECLARED ) ) { + if ( node.test.type == Syntax.UnaryExpression && + node.test.operator === "!" && + isMethodCall(node.test.argument, CALL_JQUERY_SAP_IS_DECLARED ) ) { visit(node.consequent, conditional); visit(node.alternate, true); } else { @@ -509,7 +554,9 @@ class JSModuleAnalyzer { } else { nUnnamedDefines++; if ( nUnnamedDefines > 1 ) { - throw new Error("if multiple modules are contained in a file, only one of them may omit the module ID " + name + " " + nUnnamedDefines); + throw new Error( + "if multiple modules are contained in a file, only one of them may omit the module ID " + + name + " " + nUnnamedDefines); } if ( defaultName == null ) { throw new Error("unnamed module found, but no default name given"); @@ -539,14 +586,14 @@ class JSModuleAnalyzer { if ( isString(arg) ) { const requiredModuleName = ModuleName.fromUI5LegacyName( arg.value ); info.addDependency(requiredModuleName, conditional); - } else if ( arg.type == Syntax.ConditionalExpression - && isString(arg.consequent) && isString(arg.alternate) ) { + } else if ( arg.type == Syntax.ConditionalExpression && + isString(arg.consequent) && isString(arg.alternate) ) { const requiredModuleName1 = ModuleName.fromUI5LegacyName( arg.consequent.value ); info.addDependency(requiredModuleName1, true); const requiredModuleName2 = ModuleName.fromUI5LegacyName( arg.alternate.value ); info.addDependency(requiredModuleName2, true); } else { - log.verbose("jQuery.sap.require: cannot evaluate dynamic arguments: ", arg); + log.verbose("jQuery.sap.require: cannot evaluate dynamic arguments: ", arg && arg.type); info.dynamicDependencies = true; } } @@ -558,14 +605,19 @@ class JSModuleAnalyzer { const nArgs = args.length; const i = 0; - if ( i < nArgs && isString(args[i]) ) { - const moduleName = ModuleName.fromRequireJSName( args[i].value ); - info.addDependency(moduleName, conditional); + if ( i < nArgs ) { + if ( isString(args[i]) ) { + // sap.ui.requireSync does not support relative dependencies + const moduleName = ModuleName.fromRequireJSName( args[i].value ); + info.addDependency(moduleName, conditional); + } else { + log.verbose("sap.ui.requireSync: cannot evaluate dynamic arguments: ", args[i] && args[i].type); + info.dynamicDependencies = true; + } } } - - function onSapUiPredefine(predefineCall) { + function onSapUiPredefine(predefineCall, conditional) { const args = predefineCall.arguments; const nArgs = args.length; let i = 0; @@ -574,6 +626,16 @@ class JSModuleAnalyzer { if ( i < nArgs && isString(args[i]) ) { const moduleName = ModuleName.fromRequireJSName( args[i++].value ); info.addSubModule(moduleName); + + // add dependencies + // to correctly identify dependencies e.g. of a library-preload + const elementArg = args[i++]; + if (elementArg && elementArg.type === Syntax.ArrayExpression) { + elementArg.elements.forEach((element) => { + const dependencyName = ModuleName.resolveRelativeRequireJSName(moduleName, element.value); + info.addDependency(dependencyName, conditional); + }); + } } else { log.warn("sap.ui.predefine call is missing a module name (ignored)"); } @@ -590,9 +652,11 @@ class JSModuleAnalyzer { modules = args[0]; } else { const obj = args[0]; - const version = findOwnProperty(obj, "version"); - namesUseLegacyNotation = !(version && isString(version) && parseFloat(version.value) >= 2.0); - modules = findOwnProperty(obj, "modules"); + if (obj && obj.type === Syntax.ObjectExpression) { + const version = findOwnProperty(obj, "version"); + namesUseLegacyNotation = !(version && isString(version) && parseFloat(version.value) >= 2.0); + modules = findOwnProperty(obj, "modules"); + } } if ( modules && modules.type == Syntax.ObjectExpression ) { modules.properties.forEach( function(property) { @@ -603,7 +667,7 @@ class JSModuleAnalyzer { info.addSubModule(moduleName); }); } else { - log.warn("Cannot evaluate registerPreloadedModules: '%s'", modules && modules.type); + log.verbose("Cannot evaluate registerPreloadedModules: '%s'", modules && modules.type); } } @@ -622,6 +686,9 @@ class JSModuleAnalyzer { requiredModule = ModuleName.resolveRelativeRequireJSName(name, item.value); } info.addDependency( requiredModule, conditional ); + } else { + log.verbose("sap.ui.require/sap.ui.define: cannot evaluate dynamic argument: ", item && item.type); + info.dynamicDependencies = true; } }); } diff --git a/lib/lbt/analyzer/SmartTemplateAnalyzer.js b/lib/lbt/analyzer/SmartTemplateAnalyzer.js index 4b1f4b8f6..90c7d4a90 100644 --- a/lib/lbt/analyzer/SmartTemplateAnalyzer.js +++ b/lib/lbt/analyzer/SmartTemplateAnalyzer.js @@ -39,6 +39,7 @@ const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"]; /** * Analyzes the manifest for a Smart Template App (next to its Component.js) to find more dependencies. + * * @private */ class TemplateComponentAnalyzer { @@ -62,7 +63,8 @@ class TemplateComponentAnalyzer { log.verbose("No manifest found for '%s', skipping analysis", resource.name); } } catch (err) { - log.error("an error occurred while analyzing template app %s (ignored)", resource.name, err); + log.error("an error occurred while analyzing template app %s (ignored):", resource.name); + log.error(err.stack); } return info; @@ -72,7 +74,7 @@ class TemplateComponentAnalyzer { * Evaluates a manifest after it has been read and parsed * and adds any newly found dependencies to the given info object. * - * @param {Object} manifest JSON with app descriptor structure + * @param {object} manifest JSON with app descriptor structure * @param {ModuleInfo} info ModuleInfo object that should be enriched * @returns {ModuleInfo} ModuleInfo object that should be enriched * @private @@ -104,16 +106,24 @@ class TemplateComponentAnalyzer { async _analyzeTemplateComponent(moduleName, pageConfig, appInfo) { // console.log("analyzing template component %s", moduleName); - const resource = await this._pool.findResource(moduleName); - const code = await resource.buffer(); - const ast = esprima.parseScript(code.toString()); - const defaultTemplateName = this._analyzeAST(moduleName, ast); - const templateName = (pageConfig.component && pageConfig.component.settings && - pageConfig.component.settings.templateName) || defaultTemplateName; - if ( templateName ) { - const templateModuleName = ModuleName.fromUI5LegacyName( templateName, ".view.xml" ); - log.verbose("template app: add dependency to template view %s", templateModuleName); - appInfo.addDependency(templateModuleName); + try { + const resource = await this._pool.findResource(moduleName); + const code = await resource.buffer(); + const ast = esprima.parseScript(code.toString()); + const defaultTemplateName = this._analyzeAST(moduleName, ast); + const templateName = (pageConfig.component && pageConfig.component.settings && + pageConfig.component.settings.templateName) || defaultTemplateName; + if ( templateName ) { + const templateModuleName = ModuleName.fromUI5LegacyName( templateName, ".view.xml" ); + log.verbose("template app: add dependency to template view %s", templateModuleName); + appInfo.addDependency(templateModuleName); + } + } catch (err) { + if (this._pool.getIgnoreMissingModules() && err.message.startsWith("resource not found in pool")) { + log.verbose("Ignoring missing module as per ResourcePool configuration: " + err.message); + } else { + throw err; + } } } @@ -126,10 +136,10 @@ class TemplateComponentAnalyzer { // console.log("local name for TemplateAssembler: %s", TA); if ( TA && defineCall.factory ) { defineCall.factory.body.body.forEach( (stmt) => { - if ( stmt.type === Syntax.ReturnStatement - && isMethodCall(stmt.argument, [TA, "getTemplateComponent"]) - && stmt.argument.arguments.length > 2 - && stmt.argument.arguments[2].type === "ObjectExpression" ) { + if ( stmt.type === Syntax.ReturnStatement && + isMethodCall(stmt.argument, [TA, "getTemplateComponent"]) && + stmt.argument.arguments.length > 2 && + stmt.argument.arguments[2].type === "ObjectExpression" ) { templateName = this._analyzeTemplateClassDefinition(stmt.argument.arguments[2]) || templateName; } }); diff --git a/lib/lbt/analyzer/XMLCompositeAnalyzer.js b/lib/lbt/analyzer/XMLCompositeAnalyzer.js index e69bebabf..868da94d6 100644 --- a/lib/lbt/analyzer/XMLCompositeAnalyzer.js +++ b/lib/lbt/analyzer/XMLCompositeAnalyzer.js @@ -25,8 +25,8 @@ class XMLCompositeAnalyzer { stmt.declarations.forEach( (decl) => { fragmentName = this._checkForXMLCClassDefinition( XMLC, decl.init ) || fragmentName; }); - } else if ( stmt.type === Syntax.ExpressionStatement - && stmt.expression.type === Syntax.AssignmentExpression ) { + } else if ( stmt.type === Syntax.ExpressionStatement && + stmt.expression.type === Syntax.AssignmentExpression ) { fragmentName = this._checkForXMLCClassDefinition( XMLC, stmt.expression.right ) || fragmentName; } }); diff --git a/lib/lbt/analyzer/XMLTemplateAnalyzer.js b/lib/lbt/analyzer/XMLTemplateAnalyzer.js index 58e6f7a0a..3d7e9c31b 100644 --- a/lib/lbt/analyzer/XMLTemplateAnalyzer.js +++ b/lib/lbt/analyzer/XMLTemplateAnalyzer.js @@ -76,7 +76,7 @@ function getAttributeNS(node, attrNS) { * * In an XMLView, there usually exist 3 categories of element nodes: controls, aggregations * of cardinality 'multiple' and non-UI5 nodes (e.g. XHTML or SVG). The third category usually - * can be identified by its namespace (whitelisted). To distinguish between the first and the second + * can be identified by its namespace. To distinguish between the first and the second * category, this analyzer uses a ResourcePool (provided by the caller and usually derived from the * library classpath). When the qualified node name is contained in the pool, it is assumed to * represent a control, otherwise it is ignored. @@ -150,6 +150,7 @@ class XMLTemplateAnalyzer { this.info = info; this.conditional = false; + this.templateTag = false; this.promises = []; this.busy = true; @@ -162,6 +163,12 @@ class XMLTemplateAnalyzer { return; } + if ( !result ) { + // Handle empty xml views/fragments + reject(new Error("Invalid empty XML document: " + info.name)); + return; + } + // console.log(result); // clear(); if ( isFragment ) { @@ -208,11 +215,13 @@ class XMLTemplateAnalyzer { const localName = node.$ns.local; const oldConditional = this.conditional; + const oldTemplateTag = this.templateTag; if ( namespace === TEMPLATING_NAMESPACE ) { if ( TEMPLATING_CONDITONAL_TAGS.test(localName) ) { this.conditional = true; } + this.templateTag = true; } else if ( namespace === XHTML_NAMESPACE || namespace === SVG_NAMESPACE ) { // ignore XHTML and SVG nodes @@ -292,13 +301,16 @@ class XMLTemplateAnalyzer { this._analyzeChildren(node); - // restore conditional state of the outer block + // restore conditional and templateTag state of the outer block this.conditional = oldConditional; + this.templateTag = oldTemplateTag; } _analyzeChildren(node) { if ( Array.isArray(node.$$) ) { - node.$$.forEach( (child) => this._analyzeNode( child ) ); + node.$$.forEach( (child) => { + return this._analyzeNode( child); + }); } } @@ -306,11 +318,26 @@ class XMLTemplateAnalyzer { const coreRequire = getAttributeNS(node, XMLVIEW_CORE_REQUIRE_ATTRIBUTE_NS); let requireContext; if ( coreRequire ) { + // expression binding syntax within coreRequire and a template parent node + // These expressions cannot be parsed using parseJS and if within a template tag + // represent an expression binding which needs to be evaluated before analysis + // e.g. "{= '{Handler: \'' + ${myActions > handlerModule} + '\'}'}" + if ((coreRequire.startsWith("{=") || coreRequire.startsWith("{:=")) && this.templateTag) { + log.verbose( + `Ignoring core:require: '%s' on Node %s:%s contains ` + + `an expression binding and is within a 'template' Node`, + coreRequire, node.$ns.uri, node.$ns.local + ); + return; + } + try { requireContext = JSTokenizer.parseJS(coreRequire); } catch (e) { - log.error("Ignoring core:require: Attribute can't be parsed on Node ", node.$ns.local); - log.error(coreRequire); + log.error( + "Ignoring core:require: '%s' can't be parsed on Node %s:%s", + coreRequire, node.$ns.uri, node.$ns.local + ); } if ( requireContext ) { Object.keys(requireContext).forEach((key) => { diff --git a/lib/lbt/analyzer/analyzeLibraryJS.js b/lib/lbt/analyzer/analyzeLibraryJS.js index 364d0625f..8c0e2ab7d 100644 --- a/lib/lbt/analyzer/analyzeLibraryJS.js +++ b/lib/lbt/analyzer/analyzeLibraryJS.js @@ -20,17 +20,17 @@ async function analyze(resource) { }; function visit(node) { - if ( node.type == Syntax.CallExpression - && node.callee.type === Syntax.MemberExpression - && isMethodCall(node.callee.object, CALL__SAP_UI_GETCORE) - && isIdentifier(node.callee.property, "initLibrary") - && node.arguments.length === 1 - && node.arguments[0].type === Syntax.ObjectExpression ) { + if ( node.type == Syntax.CallExpression && + node.callee.type === Syntax.MemberExpression && + isMethodCall(node.callee.object, CALL__SAP_UI_GETCORE) && + isIdentifier(node.callee.property, "initLibrary") && + node.arguments.length === 1 && + node.arguments[0].type === Syntax.ObjectExpression ) { node.arguments[0].properties.forEach( (prop) => { const key = getPropertyKey(prop); const value = prop.value; - if ( key === "noLibraryCSS" - && (value.type === Syntax.Literal && typeof value.value === "boolean") ) { + if ( key === "noLibraryCSS" && + (value.type === Syntax.Literal && typeof value.value === "boolean") ) { libInfo.noLibraryCSS = value.value; } else if ( key === "types" && value.type == Syntax.ArrayExpression ) { libInfo.types = getStringArray(value, true); @@ -84,7 +84,7 @@ async function analyze(resource) { * Note: only the first initLibrary() call that is found with a DFS on the AST, will be evaluated. * * @param {module:@ui5/fs.Resource} resource library.js resource whose content should be analyzed - * @returns {Promise} A Promise on the extract info object + * @returns {Promise} A Promise on the extract info object */ module.exports = function(resource) { if ( resource == null ) { diff --git a/lib/lbt/bundle/AutoSplitter.js b/lib/lbt/bundle/AutoSplitter.js index d98e6cd72..d9eb9091d 100644 --- a/lib/lbt/bundle/AutoSplitter.js +++ b/lib/lbt/bundle/AutoSplitter.js @@ -9,7 +9,7 @@ const escapePropertiesFile = require("../utils/escapePropertiesFile"); const log = require("@ui5/logger").getLogger("lbt:bundle:AutoSplitter"); const copyrightCommentsPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9/i; -const xmlHtmlPrePattern = /<(?:\w+:)?pre>/; +const xmlHtmlPrePattern = /<(?:\w+:)?pre\b/; /** * @@ -35,8 +35,8 @@ class AutoSplitter { /** * Runs the split operation * - * @param {Object} moduleDef - * @param {Object} options + * @param {object} moduleDef + * @param {object} options * @returns {Promise} */ async run(moduleDef, options) { @@ -47,7 +47,7 @@ class AutoSplitter { this.optimize = !!options.optimize; // ---- resolve module definition - const resolvedModule = await this.resolver.resolve(moduleDef /* NODE-TODO , vars*/); + const resolvedModule = await this.resolver.resolve(moduleDef, options); // ---- calculate overall size of merged module if ( moduleDef.configuration ) { @@ -199,7 +199,7 @@ class AutoSplitter { let fileContent = await resource.buffer(); if ( this.optimize ) { // console.log("uglify %s start", module); - const result = terser.minify({ + const result = await terser.minify({ [resource.name]: String(fileContent) }, { warnings: false, // TODO configure? @@ -211,9 +211,6 @@ class AutoSplitter { // , outFileName: resource.name // , outSourceMap: true }); - if ( result.error ) { - throw result.error; - } // console.log("uglify %s end", module); fileContent = result.code; } @@ -241,8 +238,8 @@ class AutoSplitter { // For XML we use the pretty data // Do not minify if XML(View) contains an <*:pre> tag because whitespace of // HTML
 should be preserved (should only happen rarely)
-					if (!xmlHtmlPrePattern.test(fileContent)) {
-						fileContent = pd.xmlmin(fileContent, false);
+					if (!xmlHtmlPrePattern.test(fileContent.toString())) {
+						fileContent = pd.xmlmin(fileContent.toString(), false);
 					}
 				}
 				return fileContent.length;
diff --git a/lib/lbt/bundle/Builder.js b/lib/lbt/bundle/Builder.js
index 7a010c2b9..c4993704f 100644
--- a/lib/lbt/bundle/Builder.js
+++ b/lib/lbt/bundle/Builder.js
@@ -20,8 +20,8 @@ const {SectionType} = require("./BundleDefinition");
 const BundleWriter = require("./BundleWriter");
 const log = require("@ui5/logger").getLogger("lbt:bundle:Builder");
 
-const copyrightCommentsPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9/i;
-const xmlHtmlPrePattern = /<(?:\w+:)?pre>/;
+const copyrightCommentsPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9|^@ui5-bundle-raw-include |^@ui5-bundle /i;
+const xmlHtmlPrePattern = /<(?:\w+:)?pre\b/;
 
 const strReplacements = {
 	"\r": "\\r",
@@ -37,6 +37,10 @@ function makeStringLiteral(str) {
 	}) + "'";
 }
 
+function isEmptyBundle(resolvedBundle) {
+	return resolvedBundle.sections.every((section) => section.modules.length === 0);
+}
+
 const UI5BundleFormat = {
 	beforePreloads(outW, section) {
 		outW.write(`jQuery.sap.registerPreloadedModules(`);
@@ -129,8 +133,12 @@ class BundleBuilder {
 	}
 
 	async _createBundle(module, options) {
-		const resolvedModule = await this.resolver.resolve(module /* NODE-TODO, vars */);
-		log.verbose("  create '%s'",	resolvedModule.name);
+		const resolvedModule = await this.resolver.resolve(module, options);
+		if ( options.skipIfEmpty && isEmptyBundle(resolvedModule) ) {
+			log.verbose("  skipping empty bundle " + module.name);
+			return undefined;
+		}
+		log.verbose("  create '%s'", resolvedModule.name);
 
 		this.options = options || {};
 		this.optimize = !!this.options.optimize;
@@ -256,7 +264,7 @@ class BundleBuilder {
 	async writeRawModule(module, resource) {
 		let fileContent = await resource.buffer();
 		if ( /\.js$/.test(module) ) {
-			fileContent = this.compressJS( fileContent, resource );
+			fileContent = await this.compressJS( fileContent, resource );
 		}
 		this.outW.ensureNewLine();
 		this.outW.write( fileContent );
@@ -304,12 +312,11 @@ class BundleBuilder {
 		// this.afterWriteFunctionPreloadSection();
 	}
 
-	compressJS(fileContent, resource) {
+	async compressJS(fileContent, resource) {
 		if ( this.optimize ) {
-			const result = terser.minify({
+			const result = await terser.minify({
 				[resource.name]: String(fileContent)
 			}, {
-				warnings: false, // TODO configure?
 				compress: false, // TODO configure?
 				output: {
 					comments: copyrightCommentsPattern,
@@ -318,9 +325,6 @@ class BundleBuilder {
 				// , outFileName: resource.name
 				// , outSourceMap: true
 			});
-			if ( result.error ) {
-				throw result.error;
-			}
 			// console.log(result.map);
 			// const map = new MOZ_SourceMap.SourceMapConsumer(result.map);
 			// map.eachMapping(function (m) { console.log(m); }); // console.log(map);
@@ -330,11 +334,6 @@ class BundleBuilder {
 		return fileContent;
 	}
 
-	async compressJSAsync(resource) {
-		const content = await resource.buffer();
-		return this.compressJS( content, resource );
-	}
-
 	beforeWriteFunctionPreloadSection(sequence) {
 		// simple version: just sort alphabetically
 		sequence.sort();
@@ -355,7 +354,7 @@ class BundleBuilder {
 						outW.startSegment(module);
 						outW.ensureNewLine();
 						const astAsCode = escodegen.generate(ast);
-						const fileContent = this.compressJS(astAsCode, resource);
+						const fileContent = await this.compressJS(astAsCode, resource);
 						outW.write( fileContent );
 						outW.ensureNewLine();
 						const compressedSize = outW.endSegment();
@@ -381,11 +380,19 @@ class BundleBuilder {
 	beforeWritePreloadModule(module, info, resource) {
 	}
 
+	/**
+	 *
+	 * @param {string} module module name
+	 * @param {ModuleInfo} info
+	 * @param {module:@ui5/fs.Resource} resource
+	 * @param {boolean} avoidLazyParsing
+	 * @returns {Promise}
+	 */
 	async writePreloadModule(module, info, resource, avoidLazyParsing) {
 		const outW = this.outW;
 
 		if ( /\.js$/.test(module) && (info == null || !info.requiresTopLevelScope) ) {
-			const compressedContent = await this.compressJSAsync( resource );
+			const compressedContent = await this.compressJS( await resource.buffer(), resource );
 			if ( avoidLazyParsing ) {
 				outW.write(`(`);
 			}
@@ -400,7 +407,7 @@ class BundleBuilder {
 		} else if ( /\.js$/.test(module) /* implicitly: && info != null && info.requiresTopLevelScope */ ) {
 			log.warn("**** warning: module %s requires top level scope" +
 					" and can only be embedded as a string (requires 'eval')", module);
-			const compressedContent = await this.compressJSAsync( resource );
+			const compressedContent = await this.compressJS( await resource.buffer(), resource );
 			outW.write( makeStringLiteral( compressedContent ) );
 		} else if ( /\.html$/.test(module) ) {
 			const fileContent = await resource.buffer();
@@ -411,7 +418,8 @@ class BundleBuilder {
 				try {
 					fileContent = JSON.stringify( JSON.parse( fileContent) );
 				} catch (e) {
-					log.error(e);
+					log.verbose("Failed to parse JSON file %s. Ignoring error, skipping compression.", module);
+					log.verbose(e);
 				}
 			}
 			outW.write(makeStringLiteral(fileContent));
@@ -421,7 +429,7 @@ class BundleBuilder {
 				// For XML we use the pretty data
 				// Do not minify if XML(View) contains an <*:pre> tag,
 				// because whitespace of HTML 
 should be preserved (should only happen rarely)
-				if (!xmlHtmlPrePattern.test(fileContent)) {
+				if (!xmlHtmlPrePattern.test(fileContent.toString())) {
 					fileContent = pd.xmlmin(fileContent.toString(), false);
 				}
 			}
@@ -439,12 +447,18 @@ class BundleBuilder {
 		return true;
 	}
 
+	/**
+	 * Create exports for globals
+	 *
+	 * @param {ModuleInfo} info
+	 */
 	exportGlobalNames(info) {
-		if ( !info || !info.exposedGlobalNames || !info.exposedGlobalNames.length ) {
+		if ( !info || !info.exposedGlobals || !info.exposedGlobals.length ) {
 			return;
 		}
 		this.outW.ensureNewLine();
-		info.exposedGlobalNames.forEach( (globalName) => {
+		info.exposedGlobals.forEach( (globalName) => {
+			// Note: globalName can be assumed to be a valid identifier as it is used as variable name anyhow
 			this.outW.writeln(`this.${globalName}=${globalName};`);
 		});
 	}
@@ -462,8 +476,8 @@ const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"];
 
 function rewriteDefine(targetBundleFormat, code, moduleName, avoidLazyParsing) {
 	function _injectModuleNameIfNeeded(defineCall) {
-		if ( defineCall.arguments.length == 0
-				|| defineCall.arguments[0].type !== Syntax.Literal ) {
+		if ( defineCall.arguments.length == 0 ||
+				defineCall.arguments[0].type !== Syntax.Literal ) {
 			defineCall.arguments.unshift({
 				type: Syntax.Literal,
 				value: ModuleName.toRequireJSName(moduleName)
@@ -500,19 +514,19 @@ function rewriteDefine(targetBundleFormat, code, moduleName, avoidLazyParsing) {
 	try {
 		ast = esprima.parseScript(code.toString(), {loc: true});
 	} catch (e) {
-		log.error("error while parsing %s:%s", module, e);
+		log.error("error while parsing %s: %s", moduleName, e.message);
 		return;
 	}
 
-	if ( ast.type === Syntax.Program
-			&& ast.body.length === 1
-			&& ast.body[0].type === Syntax.ExpressionStatement ) {
+	if ( ast.type === Syntax.Program &&
+			ast.body.length === 1 &&
+			ast.body[0].type === Syntax.ExpressionStatement ) {
 		// rewrite define to require.predefine
 		if ( targetBundleFormat.supportsNativeDefine() && isMethodCall(ast.body[0].expression, CALL_DEFINE) ) {
 			const defineCall = ast.body[0].expression;
 
-			if ( defineCall.callee.type === Syntax.Identifier
-					&& defineCall.callee.name === "define" ) {
+			if ( defineCall.callee.type === Syntax.Identifier &&
+					defineCall.callee.name === "define" ) {
 				defineCall.callee.name = "predefine"; // rename method to predefine
 				// add a member expression 'sap.ui.require.'
 				defineCall.callee = {
@@ -555,9 +569,9 @@ function rewriteDefine(targetBundleFormat, code, moduleName, avoidLazyParsing) {
 			const defineCall = ast.body[0].expression;
 
 			// rewrite sap.ui.define to sap.ui.predefine
-			if ( defineCall.callee.type === Syntax.MemberExpression
-					&& defineCall.callee.property.type === Syntax.Identifier
-					&& defineCall.callee.property.name === "define" ) {
+			if ( defineCall.callee.type === Syntax.MemberExpression &&
+					defineCall.callee.property.type === Syntax.Identifier &&
+					defineCall.callee.property.name === "define" ) {
 				defineCall.callee.property.name = "predefine";
 			}
 
diff --git a/lib/lbt/bundle/BundleWriter.js b/lib/lbt/bundle/BundleWriter.js
index 2862fb35a..8b63ba0ad 100644
--- a/lib/lbt/bundle/BundleWriter.js
+++ b/lib/lbt/bundle/BundleWriter.js
@@ -2,7 +2,8 @@
 
 
 const NL = "\n";
-const ENDS_WITH_NEW_LINE = /(^|\r\n|\r|\n)[ \t]*$/;
+const ENDS_WITH_NEW_LINE = /(\r\n|\r|\n)[ \t]*$/;
+const SPACES_OR_TABS_ONLY = /^[ \t]+$/;
 
 /**
  * A filtering writer that can count written chars and provides some convenience
@@ -20,11 +21,19 @@ class BundleWriter {
 		this.segments = [];
 		this.currentSegment = null;
 		this.currentSourceIndex = 0;
+		this.endsWithNewLine = true; // Initially we don't need a new line
 	}
 
 	write(...str) {
+		let writeBuf = "";
 		for ( let i = 0; i < str.length; i++ ) {
-			this.buf += str[i];
+			writeBuf += str[i];
+		}
+		if ( writeBuf.length >= 1 ) {
+			this.buf += writeBuf;
+			this.endsWithNewLine =
+				ENDS_WITH_NEW_LINE.test(writeBuf) ||
+				(this.endsWithNewLine && SPACES_OR_TABS_ONLY.test(writeBuf));
 		}
 	}
 
@@ -33,12 +42,13 @@ class BundleWriter {
 			this.buf += str[i];
 		}
 		this.buf += NL;
+		this.endsWithNewLine = true;
 	}
 
 	ensureNewLine() {
-		// TODO this regexp might be quite expensive (use of $ anchor on long strings)
-		if ( !ENDS_WITH_NEW_LINE.test(this.buf) ) {
+		if ( !this.endsWithNewLine ) {
 			this.buf += NL;
+			this.endsWithNewLine = true;
 		}
 	}
 
@@ -75,4 +85,3 @@ class BundleWriter {
 }
 
 module.exports = BundleWriter;
-
diff --git a/lib/lbt/bundle/ResolvedBundleDefinition.js b/lib/lbt/bundle/ResolvedBundleDefinition.js
index 941bf084e..74c3ba4fa 100644
--- a/lib/lbt/bundle/ResolvedBundleDefinition.js
+++ b/lib/lbt/bundle/ResolvedBundleDefinition.js
@@ -17,24 +17,24 @@ class ResolvedBundleDefinition {
 	get containsCore() {
 		return this.sections.some(
 			(section) =>
-				(section.mode === SectionType.Raw || section.mode === SectionType.Require)
-				&& section.modules.some((module) => module === UI5ClientConstants.MODULE__SAP_UI_CORE_CORE)
+				(section.mode === SectionType.Raw || section.mode === SectionType.Require) &&
+				section.modules.some((module) => module === UI5ClientConstants.MODULE__SAP_UI_CORE_CORE)
 		);
 	}
 
 	get containsGlobal() {
 		return this.sections.some(
 			(section) =>
-				section.mode === SectionType.Raw
-				&& section.modules.some((module) => module === UI5ClientConstants.MODULE__JQUERY_SAP_GLOBAL)
+				section.mode === SectionType.Raw &&
+				section.modules.some((module) => module === UI5ClientConstants.MODULE__JQUERY_SAP_GLOBAL)
 		);
 	}
 
 	executes(moduleName) {
 		return this.sections.some(
 			(section) =>
-				(section.mode === SectionType.Raw || section.mode === SectionType.Require)
-				&& section.modules.some((module) => module === moduleName)
+				(section.mode === SectionType.Raw || section.mode === SectionType.Require) &&
+				section.modules.some((module) => module === moduleName)
 		);
 	}
 
diff --git a/lib/lbt/bundle/Resolver.js b/lib/lbt/bundle/Resolver.js
index 0da795922..495704d8d 100644
--- a/lib/lbt/bundle/Resolver.js
+++ b/lib/lbt/bundle/Resolver.js
@@ -20,6 +20,7 @@ let dependencyTracker;
  * - follow dependencies, if option 'resolve' is configured for a section
  *
  * TODO ModuleResolver changes the order of the configured modules even if resolve isn't true
+ *
  * @private
  */
 class BundleResolver {
@@ -30,10 +31,14 @@ class BundleResolver {
 	// NODE-TODO private final Map moduleDefinitions;
 
 	/**
-	 * @param {ModuleDefinition} bundle
+	 * @param {ModuleDefinition} bundle Bundle definition to resolve
+	 * @param {object} [options] Options
+	 * @param {string[]} [options.defaultFileTypes]
+	 			List of default file types to which a prefix pattern shall be expanded.
 	 * @returns {Promise}
 	 */
-	resolve(bundle /* NODE-TODO, Map vars */) {
+	resolve(bundle, options) {
+		const fileTypes = (options && options.defaultFileTypes) || undefined;
 		let visitedResources = Object.create(null);
 		let selectedResources = Object.create(null);
 		let selectedResourcesSequence = [];
@@ -47,7 +52,8 @@ class BundleResolver {
 			let prevLength;
 			let newKeys;
 
-			const filters = new ResourceFilterList( section.filters ); // resolvePlaceholders(section.getFilters());
+			// NODE-TODO resolvePlaceholders(section.getFilters());
+			const filters = new ResourceFilterList( section.filters, fileTypes );
 
 			function isAccepted(resourceName, required) {
 				let match = required;
@@ -57,10 +63,10 @@ class BundleResolver {
 			}
 
 			function checkForDecomposableBundle(resource) {
-				if ( resource == null
-						|| resource.info == null
-						|| resource.info.subModules.length === 0
-						|| /(?:^|\/)library.js$/.test(resource.info.name) ) {
+				if ( resource == null ||
+						resource.info == null ||
+						resource.info.subModules.length === 0 ||
+						/(?:^|\/)library.js$/.test(resource.info.name) ) {
 					return {resource, decomposable: false};
 				}
 
@@ -117,8 +123,8 @@ class BundleResolver {
 								if ( section.resolve && dependencyInfo ) {
 									promises = dependencyInfo.dependencies.map( function(required) {
 										// ignore conditional dependencies if not configured
-										if ( !section.resolveConditional
-												&& dependencyInfo.isConditionalDependency(required) ) {
+										if ( !section.resolveConditional &&
+												dependencyInfo.isConditionalDependency(required) ) {
 											return;
 										}
 
diff --git a/lib/lbt/calls/SapUiDefine.js b/lib/lbt/calls/SapUiDefine.js
index cc5efa0da..7387a4504 100644
--- a/lib/lbt/calls/SapUiDefine.js
+++ b/lib/lbt/calls/SapUiDefine.js
@@ -2,7 +2,7 @@
 
 const {Syntax} = require("esprima");
 const ModuleName = require("../utils/ModuleName");
-const {isString} = require("../utils/ASTUtils");
+const {isString, isBoolean} = require("../utils/ASTUtils");
 
 class SapUiDefineCall {
 	constructor(node, moduleName) {
@@ -10,17 +10,29 @@ class SapUiDefineCall {
 		this.name = moduleName;
 		this.dependencyArray = null;
 		this.factory = null;
+		this.exportAsGlobal = false;
 
 		const args = node.arguments;
+		if ( args == null ) {
+			return;
+		}
+
+		// Note: the following code assumes that no variables or expressions are used
+		// for the arguments of the sap.ui.define call. The analysis could be made more
+		// sophisticated and could try to skip unhandled parameter types, based on the
+		// AST type of follow-up arguments.
+		// But on the other hand, an incomplete analysis of the define call is useless in
+		// many cases, so it might not be worth the effort.
+
 		let i = 0;
 		let params;
 
-		if ( args[i].type === Syntax.Literal ) {
+		if ( i < args.length && isString(args[i]) ) {
 			// assert(String)
 			this.name = args[i++].value;
 		}
 
-		if ( args[i].type === Syntax.ArrayExpression ) {
+		if ( i < args.length && args[i].type === Syntax.ArrayExpression ) {
 			this.dependencyArray = args[i++];
 			this.dependencies = this.dependencyArray.elements.map( (elem) => {
 				if ( !isString(elem) ) {
@@ -31,7 +43,7 @@ class SapUiDefineCall {
 			this.dependencyInsertionIdx = this.dependencyArray.elements.length;
 		}
 
-		if ( args[i].type === Syntax.FunctionExpression ) {
+		if ( i < args.length && args[i].type === Syntax.FunctionExpression ) {
 			this.factory = args[i++];
 			params = this.factory.params;
 			this.paramNames = params.map( (param) => {
@@ -45,6 +57,10 @@ class SapUiDefineCall {
 			}
 		}
 
+		if ( i < args.length && isBoolean(args[i]) ) {
+			this.exportAsGlobal = args[i].value;
+		}
+
 		// console.log("declared dependencies: " + this.dependencies);
 	}
 
diff --git a/lib/lbt/graph/dependencyGraph.js b/lib/lbt/graph/dependencyGraph.js
index 9586d1fbc..b5bbaaede 100644
--- a/lib/lbt/graph/dependencyGraph.js
+++ b/lib/lbt/graph/dependencyGraph.js
@@ -16,7 +16,7 @@ class Node {
  *
  * @param {ResourcePool} pool resource pool
  * @param {Array} roots root elements
- * @param {Object} options Options
+ * @param {object} options Options
  * @param {boolean} options.includeConditionalDependencies whether or not to include optional dependencies
  * @returns {Promise<{n0: Node, nodes: Map}>}
  */
diff --git a/lib/lbt/graph/dominatorTree.js b/lib/lbt/graph/dominatorTree.js
index 158ff0498..aa975a294 100644
--- a/lib/lbt/graph/dominatorTree.js
+++ b/lib/lbt/graph/dominatorTree.js
@@ -9,7 +9,7 @@
  * described in https://en.wikipedia.org/wiki/Dominator_(graph_theory) .
  * It has runtime O(n^2) and could be replaced by a more sophisticated one (e.g. Lengauer and Tarjan).
  *
- * @param {Object} graph Graph to calculate the DOM tree for
+ * @param {object} graph Graph to calculate the DOM tree for
  * @param {Map.} graph.nodes Nodes of the dependency graph
  * @param {Node} graph.n0 Artificial root node
  * @returns {Node} Root node of the dominator tree.
diff --git a/lib/lbt/graph/topologicalSort.js b/lib/lbt/graph/topologicalSort.js
index 21e6ad714..974fe2b23 100644
--- a/lib/lbt/graph/topologicalSort.js
+++ b/lib/lbt/graph/topologicalSort.js
@@ -34,7 +34,7 @@ class GraphNode {
  * @param {ResourcePool} pool
  * @param {string[]} moduleNames
  * @param {boolean} indegreeOnly
- * @returns {Promise}
+ * @returns {Promise}
  * @private
  */
 function createDependencyGraph(pool, moduleNames, indegreeOnly) {
diff --git a/lib/lbt/resources/LibraryFileAnalyzer.js b/lib/lbt/resources/LibraryFileAnalyzer.js
index c69af7d2a..3ca9c65ad 100644
--- a/lib/lbt/resources/LibraryFileAnalyzer.js
+++ b/lib/lbt/resources/LibraryFileAnalyzer.js
@@ -5,7 +5,7 @@
 "use strict";
 
 const xml2js = require("xml2js");
-const ModuleInfo = require("./ModuleInfo");
+const log = require("@ui5/logger").getLogger("lbt:resources:LibraryFileAnalyzer");
 
 const parser = new xml2js.Parser({
 	// explicitChildren: true,
@@ -20,43 +20,53 @@ function getAttribute(node, attr) {
 	return (node.$ && node.$[attr] && node.$[attr].value) || null;
 }
 
-function makeModuleInfo(rawModule) {
+/*
+ * Analyzes the given XML2JS object `rawModule` and creates a rawInfo object from it.
+ * @param {object} rawModule XML2JS object, representing a <raw-module> node from a .library file
+ * @returns {{name:string,dependencies?:string[],requiresTopLevelScope?:boolean,ignoredGlobals?:string[]}
+ */
+function createRawInfo(rawModule) {
 	const name = getAttribute(rawModule, "name");
-	const deps = getAttribute(rawModule, "depends");
 	if ( name ) {
-		const info = new ModuleInfo(name);
+		const rawInfo = {
+			name,
+			rawModule: true,
+			dependencies: []
+		};
+		const deps = getAttribute(rawModule, "depends");
 		if ( deps != null ) {
-			deps.trim().split(/\s*,\s*/).forEach( (dep) => info.addDependency(dep) );
+			rawInfo.dependencies = deps.trim().split(/\s*,\s*/);
+		}
+		const requiresTopLevelScope = getAttribute(rawModule, "requiresTopLevelScope");
+		if ( requiresTopLevelScope ) {
+			rawInfo.requiresTopLevelScope = requiresTopLevelScope === "true";
 		}
-		info.rawModule = true;
-		info.requiresTopLevelScope = getAttribute(rawModule, "requiresTopLevelScope") === "true";
 		const ignoredGlobals = getAttribute(rawModule, "ignoredGlobals");
 		if ( ignoredGlobals ) {
-			info.ignoredGlobals = ignoredGlobals.trim().split(/\s*,\s*/);
+			rawInfo.ignoredGlobals = ignoredGlobals.trim().split(/\s*,\s*/);
 		}
-		// console.log(info);
-		return info;
+		return rawInfo;
 	}
 }
 
-function getDependencyInfos( content ) {
+function getDependencyInfos( name, content ) {
 	const infos = {};
 	parser.parseString(content, (err, result) => {
-		// console.log(JSON.stringify(result, null, '\t'));
-		if ( result
-				&& result.library
-				&& Array.isArray(result.library.appData)
-				&& result.library.appData.length >= 1
-				&& Array.isArray(result.library.appData[0].packaging) ) {
+		if ( result &&
+				result.library &&
+				Array.isArray(result.library.appData) &&
+				result.library.appData.length >= 1 &&
+				Array.isArray(result.library.appData[0].packaging) ) {
 			result.library.appData[0].packaging.forEach( (packaging) => {
-				if ( packaging.$ns
-						&& packaging.$ns.uri === "http://www.sap.com/ui5/buildext/packaging"
-						&& Array.isArray(packaging["module-infos"]) ) {
+				if ( packaging.$ns &&
+						packaging.$ns.uri === "http://www.sap.com/ui5/buildext/packaging" &&
+						Array.isArray(packaging["module-infos"]) ) {
 					packaging["module-infos"].forEach( function(moduleInfos) {
 						moduleInfos["raw-module"] && moduleInfos["raw-module"].forEach( (rawModule) => {
-							const info = makeModuleInfo(rawModule);
-							if ( info ) {
-								infos[info.name] = info;
+							const rawInfo = createRawInfo(rawModule);
+							if ( rawInfo ) {
+								log.verbose(name + " rawInfo:", JSON.stringify(rawInfo));
+								infos[rawInfo.name] = rawInfo;
 							}
 						});
 					});
diff --git a/lib/lbt/resources/LocatorResource.js b/lib/lbt/resources/LocatorResource.js
new file mode 100644
index 000000000..0724e6698
--- /dev/null
+++ b/lib/lbt/resources/LocatorResource.js
@@ -0,0 +1,24 @@
+const Resource = require("./Resource");
+
+
+function extractName(path) {
+	return path.slice( "/resources/".length);
+}
+
+
+class LocatorResource extends Resource {
+	constructor(pool, resource) {
+		super(pool, extractName(resource.getPath()), null, resource.getStatInfo());
+		this.resource = resource;
+	}
+
+	buffer() {
+		return this.resource.getBuffer();
+	}
+
+	getProject() {
+		return this.resource._project;
+	}
+}
+
+module.exports = LocatorResource;
diff --git a/lib/lbt/resources/LocatorResourcePool.js b/lib/lbt/resources/LocatorResourcePool.js
new file mode 100644
index 000000000..104051584
--- /dev/null
+++ b/lib/lbt/resources/LocatorResourcePool.js
@@ -0,0 +1,15 @@
+const ResourcePool = require("./ResourcePool");
+const LocatorResource = require("./LocatorResource");
+
+class LocatorResourcePool extends ResourcePool {
+	prepare(resources) {
+		resources = resources.filter( (res) => !res.getStatInfo().isDirectory() );
+		return Promise.all(
+			resources.map(
+				(resource) => this.addResource( new LocatorResource(this, resource) )
+			).filter(Boolean)
+		);
+	}
+}
+
+module.exports = LocatorResourcePool;
diff --git a/lib/lbt/resources/ModuleInfo.js b/lib/lbt/resources/ModuleInfo.js
index f94da25c1..81a1b1176 100644
--- a/lib/lbt/resources/ModuleInfo.js
+++ b/lib/lbt/resources/ModuleInfo.js
@@ -2,6 +2,7 @@
 
 /**
  * A strict dependency always has to be fulfilled and is declared as part of the module's definition.
+ *
  * @private
  */
 const STRICT = 0;
@@ -9,6 +10,7 @@ const STRICT = 0;
 /**
  * An implicit dependency is also strict, but has not been declared. E.g. each UI5 module depends on
  * jquery.sap.global.
+ *
  * @private
  */
 const IMPLICIT = 1;
@@ -16,6 +18,7 @@ const IMPLICIT = 1;
 /**
  * A conditional dependency has to be resolved only under certain conditions that typically are
  * checked at runtime.
+ *
  * @private
  */
 const CONDITIONAL = 2;
@@ -55,6 +58,12 @@ class ModuleInfo {
 		/**
 		 * 'raw' modules are modules that don't use UI5's module system (require/declare)
 		 * TODO align with module format (ui5, amd, es6, raw)
+		 *
+		 * A raw module is a module which does not have in its non-conditional execution:
+		 * 
    + *
  • sap.ui.define call
  • + *
  • jQuery.sap.declare call
  • + *
*/ this.rawModule = false; @@ -105,10 +114,10 @@ class ModuleInfo { // If the dependency was known already, update the kind // only when the new kind is stronger than the current one. // STRICT is stronger than IMPLICIT, IMPLICIT is stronger than CONDITIONAL - if ( dependency - && dependency !== this.name - && this.subModules.indexOf(dependency) < 0 - && ( !(dependency in this._dependencies) || kind < this._dependencies[dependency]) ) { + if ( dependency && + dependency !== this.name && + this.subModules.indexOf(dependency) < 0 && + ( !(dependency in this._dependencies) || kind < this._dependencies[dependency]) ) { this._dependencies[dependency] = kind; } } @@ -122,9 +131,9 @@ class ModuleInfo { } setFormat(detectedFormat) { - if ( this.format == null - || detectedFormat === Format.UI5_LEGACY - || (detectedFormat === Format.UI5_DEFINE && this.format !== Format.UI5_LEGACY) ) { + if ( this.format == null || + detectedFormat === Format.UI5_LEGACY || + (detectedFormat === Format.UI5_DEFINE && this.format !== Format.UI5_LEGACY) ) { this.format = detectedFormat; } } @@ -149,10 +158,8 @@ class ModuleInfo { if ( other instanceof ModuleInfo ) { this.addSubModule( other.name ); // accumulate dependencies - for ( const dep in other._dependencies ) { - if (other._dependencies.hasOwnProperty(dep)) { - this._addDependency(dep, other._dependencies[dep]); - } + for ( const dep of Object.keys(other._dependencies ) ) { + this._addDependency(dep, other._dependencies[dep]); } // inherit dynamic dependencies if ( other.dynamicDependencies ) { @@ -195,6 +202,18 @@ class ModuleInfo { return Object.keys(this._dependencies); } + /** + * Removes the given set of `ignoredGlobals` from the set of exposed global names. + * + * @param {string[]} ignoredGlobals Names to ignore (determined from shims in .library) + */ + removeIgnoredGlobalNames(ignoredGlobals) { + if ( this.exposedGlobals ) { + const remaining = this.exposedGlobals.filter((global) => !ignoredGlobals.includes(global)); + this.exposedGlobals = remaining.length > 0 ? remaining : null; + } + } + toString() { return "ModuleInfo(" + this.name + @@ -229,13 +248,6 @@ public class ModuleInfo { * private boolean excludeFromAllInOne; - - public void removeIgnoredGlobalNames(Collection ignoredNames) { - if ( !exposedGlobals.isEmpty() ) { - exposedGlobals.removeAll(ignoredNames); - } - } - } */ module.exports = ModuleInfo; diff --git a/lib/lbt/resources/Resource.js b/lib/lbt/resources/Resource.js index 577e708cc..294379638 100644 --- a/lib/lbt/resources/Resource.js +++ b/lib/lbt/resources/Resource.js @@ -1,7 +1,7 @@ "use strict"; const {promisify} = require("util"); -const fs = require("fs"); +const fs = require("graceful-fs"); const readFile = promisify(fs.readFile); class Resource { diff --git a/lib/lbt/resources/ResourceCollector.js b/lib/lbt/resources/ResourceCollector.js new file mode 100644 index 000000000..5eb6095ad --- /dev/null +++ b/lib/lbt/resources/ResourceCollector.js @@ -0,0 +1,336 @@ +const ResourceInfoList = require("./ResourceInfoList"); +const ResourceFilterList = require("./ResourceFilterList"); +const ResourceInfo = require("./ResourceInfo"); + + +const LOCALE = /^((?:[^/]+\/)*[^/]+?)_([A-Z]{2}(?:_[A-Z]{2}(?:_[A-Z0-9_]+)?)?)(\.properties|\.hdbtextbundle)$/i; +const THEME = /^((?:[^/]+\/)*)themes\/([^/]+)\//; + +const log = require("@ui5/logger").getLogger("lbt:resources:ResourceCollector"); + +/** + * Collects all resources in a set of resource folders or from an archive + * and writes a 'resources.json' file for each component or library + * that can be found in the resources. + * + * @since 1.29.0 + */ +class ResourceCollector { + /** + * Collects a set of ResourceInfo objects and groups them by components, libraries and themes. + * + * @param {ResourcePool} pool + * @param {ResourceFilterList} [filter] used to filter the resources based on their name + */ + constructor(pool, filter) { + this._pool = pool; + /** + * Global filters that should be taken into account when collecting resources. + * + * @type {ResourceFilterList} + * @private + */ + this._filter = filter != null ? filter : new ResourceFilterList(); + /** + * name to resource info + * + * @type {Map} + */ + this._resources = new Map(); + + /** + * prefix to ResourceInfoList + * + * @type {Map} + * @private + */ + this._components = new Map(); + + /** + * prefix to ResourceInfoList + * + * @type {Map} + * @private + */ + this._themePackages = new Map(); + } + + /** + * Comma separated list of components to which orphaned resources should be added. + * + * A component and a separated list of resource patterns of orphans that should be added + * to the preceding component. + * If no such list is given, any orphaned resource will be added to the component. + * The evaluation logic for the filter list is the same as for the filters + * parameters: excludes can be denoted with a leading '-' or '!' and order is significant. + * Later filters can override the result of earlier ones. + * + * If no component is given, orphans will only be reported but not added to any component (default). + * + * @param {object} list component to list of components + */ + setExternalResources(list) { + this._externalResources = list; + } + + /** + * Processes a resource + * + * @param {module:@ui5/fs.Resource} resource + */ + async visitResource(resource) { + const virPath = resource.getPath(); + if ( !virPath.startsWith("/resources/") ) { + log.warn(`non-runtime resource ${virPath} ignored`); + return; + } + const name = virPath.slice("/resources/".length); + if ( this._filter.matches(name) ) { + const resourceInfo = new ResourceInfo(name); + resourceInfo.size = await resource.getSize(); + this._resources.set(name, resourceInfo); + + const p = name.lastIndexOf("/"); + const prefix = name.substring(0, p + 1); + const basename = name.substring(p + 1); + if ( basename.match("[^/]*\\.library|Component\\.js|manifest\\.json") && !this._components.has(prefix) ) { + this._components.set(prefix, new ResourceInfoList(prefix)); + } + // a .theme file within a theme folder indicates a library/theme package + // Note: ignores .theme files in library folders + + // .theming files are not always present therefore this check is relevant for the library.source.less + if ( name.match("(?:[^/]+/)*themes/[^/]+/(?:\\.theming|library\\.source\\.less)") && + !this._themePackages.has(prefix) ) { + // log.info("found new theme package %s", prefix); + this._themePackages.set(prefix, new ResourceInfoList(prefix)); + } + } + } + + async enrichWithDependencyInfo(resourceInfo) { + return this._pool.getModuleInfo(resourceInfo.name).then((moduleInfo) => { + if ( moduleInfo.name ) { + resourceInfo.module = moduleInfo.name; + } + if ( moduleInfo.dynamicDependencies ) { + resourceInfo.dynRequired = true; + } + if ( moduleInfo.dependencies.length > 0 ) { + resourceInfo.required = resourceInfo.required || new Set(); + resourceInfo.condRequired = resourceInfo.condRequired || new Set(); + moduleInfo.dependencies.forEach((dep) => { + if ( moduleInfo.isConditionalDependency(dep) ) { + resourceInfo.condRequired.add(dep); + } else if ( !moduleInfo.isImplicitDependency(dep) ) { + resourceInfo.required.add(dep); + } + }); + } + if ( moduleInfo.subModules.length > 0 ) { + resourceInfo.included = resourceInfo.included || new Set(); + moduleInfo.subModules.forEach((mod) => { + resourceInfo.included.add(mod); + }); + } + + if (moduleInfo.requiresTopLevelScope) { + resourceInfo.requiresTopLevelScope = true; + } + if (moduleInfo.exposedGlobals != null && moduleInfo.exposedGlobals.length) { + resourceInfo.exposedGlobalNames = resourceInfo.exposedGlobalNames || new Set(); + moduleInfo.exposedGlobals.forEach((exposedGlobalName) => { + resourceInfo.exposedGlobalNames.add(exposedGlobalName); + }); + } + + if (moduleInfo.rawModule) { + resourceInfo.format = "raw"; + } + }); + } + + async determineResourceDetails({ + debugResources, mergedResources, designtimeResources, supportResources, debugBundles + }) { + const baseNames = new Set(); + const debugFilter = new ResourceFilterList(debugResources); + const mergeFilter = new ResourceFilterList(mergedResources); + const designtimeFilter = new ResourceFilterList(designtimeResources); + const supportFilter = new ResourceFilterList(supportResources); + const debugBundleFilter = new ResourceFilterList(debugBundles); + + const promises = []; + const nonBundledDebugResources = []; + + for (const [name, info] of this._resources.entries()) { + if ( debugFilter.matches(name) ) { + info.isDebug = true; + log.verbose(` found potential debug resource '${name}'`); + } + + // log.verbose(` checking ${name}`); + let m; + if ( m = LOCALE.exec(name) ) { + const baseName = m[1] + m[3]; + log.verbose(` found potential i18n resource '${name}', base name is '${baseName}', locale is ${m[2]}`); + info.i18nName = baseName; // e.g. "i18n.properties" + info.i18nLocale = m[2]; // e.g. "de" + baseNames.add(baseName); + } + + if ( m = THEME.exec(name) ) { + // log.verbose("found theme candidate %s with prefix %s", name, m[1]); + if ( this._themePackages.has(m[0]) ) { + const theme = m[2]; + info.theme = theme; + log.verbose(` found potential theme resource '${name}', theme ${theme}`); + } + } + + if ( /(?:\.js|\.view\.xml|\.control\.xml|\.fragment\.xml)$/.test(name) ) { + if ( (!info.isDebug || debugBundleFilter.matches(name)) ) { + // Only analyze non-debug files and special debug bundles (like sap-ui-core-dbg.js) + promises.push( + this.enrichWithDependencyInfo(info) + ); + } else { + nonBundledDebugResources.push(info); + } + } + + // set the module name for .properties and .json + if ( /(?:\.properties|\.json)$/.test(name) ) { + promises.push(new Promise((resolve) => { + return this._pool.getModuleInfo(info.name).then((moduleInfo) => { + if (moduleInfo.name) { + info.module = moduleInfo.name; + } + resolve(); + }); + })); + } + + if ( mergeFilter.matches(name) ) { + info.merged = true; + log.verbose(` found potential merged resource '${name}'`); + } + + if ( designtimeFilter.matches(name) ) { + info.designtime = true; + log.verbose(` found potential designtime resource '${name}'`); + } + + if ( supportFilter.matches(name) ) { + info.support = true; + log.verbose(` found potential support resource '${name}'`); + } + } + + for (const baseName of baseNames) { + if ( this._resources.has(baseName) ) { + const info = this._resources.get(baseName); + info.i18nName = baseName; + info.i18nLocale = ""; + } + } + + await Promise.all(promises); + + for (let i = nonBundledDebugResources.length - 1; i >= 0; i--) { + const dbgInfo = nonBundledDebugResources[i]; + const nonDebugName = ResourceInfoList.getNonDebugName(dbgInfo.name); + const nonDbgInfo = this._resources.get(nonDebugName); + const newDbgInfo = new ResourceInfo(dbgInfo.name); + + // First copy info of analysis from non-dbg file (included, required, condRequired, ...) + newDbgInfo.copyFrom(null, nonDbgInfo); + // Then copy over info from dbg file to properly set name, isDebug, etc. + newDbgInfo.copyFrom(null, dbgInfo); + + this._resources.set(dbgInfo.name, newDbgInfo); + } + } + + createOrphanFilters() { + log.verbose( + ` configured external resources filters (resources outside the namespace): ` + + `${this._externalResources == null ? "(none)" : this._externalResources}`); + + const filtersByComponent = new Map(); + + if ( this._externalResources != null ) { + for ( let [component, filters] of Object.entries(this._externalResources) ) { + const packageFilters = new ResourceFilterList(filters); + if ( component === "/" || component === "" ) { + component = ""; + } else if ( !component.endsWith("/") ) { + component += "/"; + } + log.verbose(` resulting filter list for '${component}': '${packageFilters}'`); + filtersByComponent.set(component, packageFilters); + } + } + return filtersByComponent; + } + + groupResourcesByComponents() { + const orphanFilters = this.createOrphanFilters(); + for (const resource of this._resources.values()) { + let contained = false; + for (const [prefix, list] of this._components.entries()) { + if ( resource.name.startsWith(prefix) ) { + list.add(resource); + contained = true; + } else if ( orphanFilters.has(prefix) ) { + // log.verbose(` checking '${resource.name}' against orphan filter ` + + // `'${orphanFilters.get(prefix)}' (${prefix})`); + if ( orphanFilters.get(prefix).matches(resource.name) ) { + list.add(resource); + contained = true; + } + } + } + + if ( resource.theme != null ) { + // assign theme resources additionally to theme packages + for (const [prefix, list] of this._themePackages.entries()) { + if ( resource.name.startsWith(prefix) ) { + list.add(resource); + contained = true; + } + } + } + + if ( contained ) { + this._resources.delete(resource.name); + } + } + } + + /** + * + * @returns {Set} resource names + */ + get resources() { + return new Set(this._resources.keys()); + } + + /** + * Components + * + * @returns {Map} + */ + get components() { + return this._components; + } + + /** + * @returns {Map} + */ + get themePackages() { + return this._themePackages; + } +} + +module.exports = ResourceCollector; diff --git a/lib/lbt/resources/ResourceFilterList.js b/lib/lbt/resources/ResourceFilterList.js index cef22f699..e29301177 100644 --- a/lib/lbt/resources/ResourceFilterList.js +++ b/lib/lbt/resources/ResourceFilterList.js @@ -2,7 +2,19 @@ const log = require("@ui5/logger").getLogger("lbt:resources:ResourceFilterList"); -function makeMatcher(globPattern) { +function makeFileTypePattern(fileTypes) { + if ( fileTypes == null ) { + return undefined; + } + return "(?:" + fileTypes.map((type) => { + if ( !type.startsWith(".") ) { + type = "." + type; + } + return type.replace(/[*+?.()|^$]/g, "\\$&"); + }).join("|") + ")"; +} + +function makeMatcher(globPattern, fileTypesPattern) { const result = { pattern: globPattern, include: true @@ -14,29 +26,53 @@ function makeMatcher(globPattern) { globPattern = globPattern.slice(1); } - // check for wildcards - if ( /\*|\/$/.test(globPattern) ) { - if ( !/\/\*\*\/$/.test(globPattern) ) { - globPattern = globPattern.replace(/\/$/, "/**/"); + // normalize some convenience shortcuts + // - a lonely 'any sub-path' pattern implies the 'any file' pattern: + // "**/" --> "**/*" + // - a trailing 'any sub-path' pattern also implies the 'any file' pattern: + // ".../foo/**/" --> "../foo/**/*" + // - any other trailing slash matches any files in any sub-folder: + // ".../foo/" --> ".../foo/**/*" + if ( globPattern.endsWith("/") ) { + if ( globPattern === "**/" || globPattern.endsWith("/**/") ) { + globPattern = globPattern + "*"; + } else { + globPattern = globPattern + "**/*"; } + } - const regexp = globPattern.replace(/\*\*\/|\*|[[\]{}()+?.\\^$|]/g, function(match) { + // check for wildcards + if ( /\*/.test(globPattern) ) { + // Transform the globPattern into a regular expression pattern by converting + // the "all sub-directories" pattern "/**/" and the "any file name" pattern "*" + // to their respective regexp counterparts and escape all other regexp special + // characters. + let regexp = globPattern.replace(/^\*\*\/|\/\*\*\/|\*|[[\]{}()+?.\\^$|]/g, (match) => { switch (match) { case "**/": return "(?:[^/]+/)*"; + case "/**/": return "/(?:[^/]+/)*"; case "*": return "[^/]*"; default: return "\\" + match; } }); - log.verbose("%s -> %s,%s", result.pattern, "^" + regexp, result.include ? "include" : "exclude" ); - result.regexp = new RegExp("^" + regexp); + // if the pattern ended with an asterisk and if a default file type pattern is defined, + // add that pattern. This limits the matches to the specified set of file types + if ( fileTypesPattern != null && regexp.endsWith("[^/]*") ) { + regexp = regexp + fileTypesPattern; + } + + result.regexp = new RegExp("^" + regexp + "$"); result.calcMatch = result.include ? function(candidate, matchSoFar) { return matchSoFar || this.regexp.test(candidate); } : function(candidate, matchSoFar) { return matchSoFar && !this.regexp.test(candidate); }; + + log.verbose(` ${result.pattern} --> ${result.include ? "include" : "exclude"}: /${result.regexp.source}/`); } else { result.value = globPattern; + log.verbose(` ${result.pattern} --> ${result.include ? "include" : "exclude"}: "${globPattern}"`); result.calcMatch = result.include ? function(candidate, matchSoFar) { return matchSoFar || candidate === this.value; } : function(candidate, matchSoFar) { @@ -56,19 +92,20 @@ function makeMatcher(globPattern) { * @author Frank Weigel * @since 1.16.2 * @private - * TODO Share with plugins, esp. coldWater, lightening, ... */ class ResourceFilterList { - constructor(filters) { + constructor(filters, fileTypes) { this.matchers = []; this.matchByDefault = true; + this.fileTypes = makeFileTypePattern(fileTypes); + log.verbose(`filetypes: ${fileTypes}`); this.addFilters(filters); } addFilters(filters) { if ( Array.isArray(filters) ) { filters.forEach( (filter) => { - const matcher = makeMatcher(filter); + const matcher = makeMatcher(filter, this.fileTypes); this.matchers.push( matcher ); this.matchByDefault = this.matchByDefault && !matcher.include; }); @@ -78,59 +115,6 @@ class ResourceFilterList { return this; } - /* NODE-TODO - public ResourceFilterList addIncludes(String[] includes){ - if ( includes != null ) { - for(String include : includes) { - add(include, false); - } - } - return this; - } - - public ResourceFilterList addExcludes(String[] excludes) { - if ( excludes != null ) { - for(String exclude : excludes) { - add(exclude, true); - } - } - return this; - } - - /** - * old style resource pattern (from old Optimizer) - * @param excludePattern - * @deprecated Use the more flexible add or addFilters instead. - * - public void addExcludePattern(Pattern excludePattern) { - isExclude.set(patterns.size(), true); - patterns.add(excludePattern); - } - - public ResourceFilterList add(String patternList, boolean exclude) { - for(String pattern : patternList.trim().split("\\s*,\\s*")) { - if ( !pattern.isEmpty() ) { - isExclude.set(patterns.size(), exclude); - patterns.add(ModuleNamePattern.createRegEx(pattern, ignoreCase)); - hasInclude = hasInclude || !exclude; - } - } - return this; - } - - public ResourceFilterList add(String patternList) { - for(String pattern : patternList.trim().split("\\s*,\\s*")) { - if ( !pattern.isEmpty() ) { - boolean exclude = pattern.startsWith("!") || pattern.startsWith("-"); - isExclude.set(patterns.size(), exclude); - patterns.add(ModuleNamePattern.createRegEx(exclude || pattern.startsWith("+") - ? pattern.substring(1) : pattern, ignoreCase)); - hasInclude = hasInclude || !exclude; - } - } - return this; - } */ - matches(candidate, initialMatch) { return this.matchers.reduce( (acc, cur) => cur.calcMatch(candidate, acc), @@ -143,10 +127,36 @@ class ResourceFilterList { } } +/** + * Each filter entry can be a comma separated list of simple filters. Each simple filter + * can be a pattern in resource name pattern syntax: A double asterisk '&0x2a;&0x2a;/' denotes an arbitrary + * number of resource name segments (folders) incl. a trailing slash, whereas a simple asterisk '*' + * denotes an arbitrary number of resource name characters, but not the segment separator '/'. + * A dot is interpreted as a dot, all other special regular expression characters keep their + * special meaning. This is a mixture of ANT-style path patterns and regular expressions. + * + * Excludes can be denoted by a leading '-' or '!', includes optionally by a leading '+'. + * Order of filters is significant, a later exclusion overrides an earlier inclusion + * and vice versa. + * + * Example: + *
+ *	 !sap/ui/core/
+ *	 +sap/ui/core/utils/
+ * 
+ * excludes everything from sap/ui/core, but includes everything from the subpackage sap/ui/core/utils/. + * + * Note that the filter operates on the full name of each resource. If a resource name + * prefix is configured for a resource set, the filter will be applied + * to the combination of prefix and local file path and not only to the local file path. + * + * @param {string} filterStr comma separated list of simple filters + * @returns {ResourceFilterList} + */ ResourceFilterList.fromString = function(filterStr) { const result = new ResourceFilterList(); if ( filterStr != null ) { - result.addFilters( filterStr.trim().split(/\s*,\s*/) ); + result.addFilters( filterStr.trim().split(/\s*,\s*/).filter(Boolean) ); } return result; }; diff --git a/lib/lbt/resources/ResourceInfo.js b/lib/lbt/resources/ResourceInfo.js new file mode 100644 index 000000000..a6a378473 --- /dev/null +++ b/lib/lbt/resources/ResourceInfo.js @@ -0,0 +1,180 @@ +/** + * Information about a single resource as stored in the resources.json file. + * + * @author Frank Weigel + * @since 1.33.0 + */ +class ResourceInfo { + /** + * @param {string} name name of the resource + */ + constructor(name) { + this.name = name; + this.i18nName = null; + this.i18nLocale = null; + this.isDebug = false; + this.theme = null; + this.merged = false; + this.designtime = false; + this.support = false; + this._module = null; + this.required = null; + this.condRequired = null; + this.included = null; + this.dynRequired = false; + this.requiresTopLevelScope = false; + this.exposedGlobalNames = null; + this._format = null; + this._size = -1; + } + + + get module() { + return this._module; + } + + set module(value) { + this._module = value; + } + + get format() { + return this._format; + } + + set format(value) { + this._format = value; + } + + get size() { + return this._size; + } + + set size(value) { + this._size = value; + } + + /** + * Copies the properties of the given ResourceInfo into this + * + * @param {string} prefix + * @param {ResourceInfo} orig + */ + copyFrom(prefix, orig) { + this.i18nName = orig.i18nName; + this.i18nLocale = orig.i18nLocale; + this.isDebug = orig.isDebug; + this.theme = orig.theme; + this.merged = orig.merged; + this.designtime = orig.designtime; + this.support = orig.support; + if ( this.module == null ) { + this.module = orig.module; + } + if ( orig.required != null ) { + if ( this.required == null ) { + this.required = new Set(); + } + orig.required.forEach(this.required.add, this.required); + } + if ( orig.condRequired != null ) { + if ( this.condRequired == null ) { + this.condRequired = new Set(); + } + orig.condRequired.forEach(this.condRequired.add, this.condRequired); + } + if ( orig.dynRequired ) { + this.dynRequired = orig.dynRequired; + } + if ( orig.included != null ) { + if ( this.included == null ) { + this.included = new Set(); + } + orig.included.forEach(this.included.add, this.included); + } + if ( this.included != null && this.included.size > 0 ) { + this.merged = true; + } + if (orig.size >= 0) { + this.size = orig.size; + } + if ( orig.requiresTopLevelScope ) { + this.requiresTopLevelScope = orig.requiresTopLevelScope; + } + if ( orig.exposedGlobalNames != null ) { + if ( this.exposedGlobalNames == null ) { + this.exposedGlobalNames = new Set(); + } + orig.exposedGlobalNames.forEach(this.exposedGlobalNames.add, this.exposedGlobalNames); + } + if ( orig.format != null ) { + this.format = orig.format; + } + } + + /** + * called from JSON.stringify() + * + * @returns {{name: *}} + */ + toJSON() { + const result = { + name: this.name + }; + if ( this._module != null ) { + result.module = this.module; + } + if ( this.size >= 0 ) { + result.size = this.size; + } + if ( this.requiresTopLevelScope ) { + result.requiresTopLevelScope = this.requiresTopLevelScope; + } + if ( this.exposedGlobalNames != null && this.exposedGlobalNames.size > 0 ) { + result.exposedGlobalNames = [...this.exposedGlobalNames]; + } + if ( this.format ) { + result.format = this.format; + } + + // + + if ( this.isDebug ) { + result.isDebug = this.isDebug; + } + if ( this.merged ) { + result.merged = this.merged; + } + if ( this.designtime ) { + result.designtime = this.designtime; + } + if ( this.support ) { + result.support = this.support; + } + if ( this.i18nLocale != null ) { + result.locale = this.i18nLocale; + result.raw = this.i18nName; + } + if ( this.theme != null ) { + result.theme = this.theme; + } + + // + + if ( this.required != null && this.required.size > 0 ) { + result.required = [...this.required].sort(); + } + if ( this.condRequired != null && this.condRequired.size > 0 ) { + result.condRequired = [...this.condRequired].sort(); + } + if ( this.dynRequired ) { + result.dynRequired = this.dynRequired; + } + if ( this.included != null && this.included.size > 0 ) { + result.included = [...this.included]; + } + + return result; + } +} + +module.exports = ResourceInfo; diff --git a/lib/lbt/resources/ResourceInfoList.js b/lib/lbt/resources/ResourceInfoList.js new file mode 100644 index 000000000..1a87b2f8e --- /dev/null +++ b/lib/lbt/resources/ResourceInfoList.js @@ -0,0 +1,118 @@ +const ResourceInfo = require("./ResourceInfo"); + +const DEBUG_RESOURCES_PATTERN = /-dbg((?:\.view|\.fragment|\.controller|\.designtime|\.support)?\.js|\.css)$/; + +/** + * A list of ResourceInfo objects, suitable for (but not dependent on) JSON serialization. + * + * @author Frank Weigel + * @since 1.33.0 + */ +class ResourceInfoList { + /** + * Holds ResourceInfos + * + * @param {string} prefix + */ + constructor(prefix) { + /** + * List of resources information objects + * + * @type {ResourceInfo[]} + */ + this.resources = []; + + // --- transient state --- + /** + * @type {string} name of the resource + */ + this.name = prefix; + /** + * + * @type {Map} + */ + this.resourcesByName = new Map(); + } + + /** + * Add ResourceInfo to list + * + * @param {ResourceInfo} info + */ + add(info) { + const relativeName = ResourceInfoList.makePathRelativeTo(this.name, info.name); + // search for a resource with the same name + let myInfo = this.resourcesByName.get(relativeName); + + // this is the assumption, that the debug one is the same as the non-dbg one + if ( myInfo == null ) { + myInfo = new ResourceInfo(relativeName); + myInfo.size = info.size; + myInfo.module = ResourceInfoList.getNonDebugName(info.name); + this.resources.push(myInfo); + this.resourcesByName.set(relativeName, myInfo); + } + myInfo.copyFrom(this.name, info); + if (info.i18nName) { + myInfo.i18nName = ResourceInfoList.makePathRelativeTo(this.name, info.i18nName); + } + } + + /** + * Serializes its content to JSON format + * + * @returns {{resources: ResourceInfo[], _version: string}} + */ + toJSON() { + this.resources.sort((a, b) => { + if ( a.name === b.name ) { + return 0; + } + return a.name < b.name ? -1 : 1; + }); + return { + /** + * Version of the resources.json file format, must be 1.1.0 or higher to store dependencies + */ + _version: "1.1.0", + resources: this.resources + }; + } + + /** + * Retrieves the relative path + * + * @param {string} prefix + * @param {string} name + * @returns {string} + */ + static makePathRelativeTo(prefix, name) { + let back = ""; + while ( !name.startsWith(prefix) ) { + const p = prefix.lastIndexOf("/", prefix.length - 2); + back = back + "../"; + if ( p >= 0 ) { + prefix = prefix.slice(0, p + 1); + } else { + prefix = ""; + break; + } + } + return back + name.slice(prefix.length); + } + + /** + * If the given module is a -dbg file, calculate and return the non-dbg name. + * + * @param {string} path + * @returns {string|null} Non-debug name of the module + */ + static getNonDebugName(path) { + if ( DEBUG_RESOURCES_PATTERN.test(path) ) { + return path.replace( DEBUG_RESOURCES_PATTERN, "$1"); + } + return null; + } +} + +module.exports = ResourceInfoList; diff --git a/lib/lbt/resources/ResourcePool.js b/lib/lbt/resources/ResourcePool.js index 2624eddeb..fa1e8b35e 100644 --- a/lib/lbt/resources/ResourcePool.js +++ b/lib/lbt/resources/ResourcePool.js @@ -65,22 +65,34 @@ async function determineDependencyInfo(resource, rawInfo, pool) { const code = await resource.buffer(); info.size = code.length; const promises = []; + let ast; try { - const ast = esprima.parseScript(code.toString(), {comment: true}); - jsAnalyzer.analyze(ast, resource.name, info); - new XMLCompositeAnalyzer(pool).analyze(ast, resource.name, info); - } catch (error) { - log.error("failed to parse or analyze %s:", resource.name, error); + ast = esprima.parseScript(code.toString(), {comment: true}); + } catch (err) { + log.error("failed to parse %s: %s", resource.name, err.message); + } + if (ast) { + try { + jsAnalyzer.analyze(ast, resource.name, info); + new XMLCompositeAnalyzer(pool).analyze(ast, resource.name, info); + } catch (error) { + log.error("failed to analyze %s: %s", resource.name, error.stack); + } } if ( rawInfo ) { info.rawModule = true; // console.log("adding preconfigured dependencies for %s:", resource.name, rawInfo.dependencies); - rawInfo.dependencies.forEach( (dep) => info.addDependency(dep) ); - if ( rawInfo.requiresTopLevelScope ) { - info.requiresTopLevelScope = true; + if ( rawInfo.dependencies ) { + rawInfo.dependencies.forEach( (dep) => info.addDependency(dep) ); } + + if ( rawInfo.requiresTopLevelScope != null ) { + // an explicitly defined value for requiresTopLevelScope from .library overrides analysis result + info.requiresTopLevelScope = rawInfo.requiresTopLevelScope; + } + if ( rawInfo.ignoredGlobals ) { - info.ignoredGlobals = rawInfo.ignoredGlobals; + info.removeIgnoredGlobalNames(rawInfo.ignoredGlobals); } } if ( /(?:^|\/)Component\.js/.test(resource.name) ) { @@ -112,7 +124,8 @@ async function determineDependencyInfo(resource, rawInfo, pool) { } class ResourcePool { - constructor() { + constructor({ignoreMissingModules} = {}) { + this._ignoreMissingModules = !!ignoreMissingModules; // this._roots = []; this._resources = []; this._resourcesByName = new Map(); @@ -152,16 +165,20 @@ class ResourcePool { if ( /\.library$/.test(resource.name) ) { // read raw-module info from .library files return resource.buffer().then( (buffer) => { - const infos = LibraryFileAnalyzer.getDependencyInfos( buffer ); - for ( const name in infos ) { - if (infos.hasOwnProperty(name)) { - this._rawModuleInfos.set(name, infos[name]); - } + const infos = LibraryFileAnalyzer.getDependencyInfos( resource.name, buffer ); + for ( const name of Object.keys(infos) ) { + this._rawModuleInfos.set(name, infos[name]); } }); } } + /** + * Retrieves the module info + * + * @param {string} name module name + * @returns {Promise} + */ async getModuleInfo(name) { let info = this._dependencyInfos.get(name); if ( info == null ) { @@ -177,6 +194,8 @@ class ResourcePool { async findResource(name) { const resource = this._resourcesByName.get(name); if ( resource == null ) { + // TODO: Remove throw and return null to align with ui5-fs + // This would require changes in most consuming classes throw new Error("resource not found in pool: '" + name + "'"); } return resource; @@ -212,6 +231,10 @@ class ResourcePool { get resources() { return this._resources.slice(); } + + getIgnoreMissingModules() { + return this._ignoreMissingModules; + } } module.exports = ResourcePool; diff --git a/lib/lbt/utils/ASTUtils.js b/lib/lbt/utils/ASTUtils.js index c528d7931..dc8ec8dee 100644 --- a/lib/lbt/utils/ASTUtils.js +++ b/lib/lbt/utils/ASTUtils.js @@ -19,6 +19,13 @@ function isString(node, literal) { return literal == null ? true : node.value === literal; } +function isBoolean(node, literal) { + if ( node == null || node.type !== Syntax.Literal || typeof node.value !== "boolean" ) { + return false; + } + return literal == null ? true : node.value === literal; +} + function isMethodCall(node, methodPath) { if ( node.type !== Syntax.CallExpression ) { return false; @@ -30,9 +37,9 @@ function isMethodCall(node, methodPath) { function isNamedObject(node, objectPath, length) { // console.log("checking for named object ", node, objectPath, length); - while ( length > 1 - && node.type === Syntax.MemberExpression - && isIdentifier(node.property, objectPath[length-1]) ) { + while ( length > 1 && + node.type === Syntax.MemberExpression && + isIdentifier(node.property, objectPath[length-1]) ) { node = node.object; length--; } @@ -106,6 +113,7 @@ function getStringArray(array, skipNonStringLiterals) { module.exports = { isString, + isBoolean, isMethodCall, isNamedObject, isIdentifier, diff --git a/lib/lbt/utils/escapePropertiesFile.js b/lib/lbt/utils/escapePropertiesFile.js index 3e8158398..5139d035e 100644 --- a/lib/lbt/utils/escapePropertiesFile.js +++ b/lib/lbt/utils/escapePropertiesFile.js @@ -11,11 +11,22 @@ const nonAsciiEscaper = require("../../processors/nonAsciiEscaper"); * @returns {Promise} resolves with the escaped string content of the given Resource */ module.exports = async function(resource) { - const propertiesFileSourceEncoding = resource.getProject() - && resource.getProject().resources - && resource.getProject().resources.configuration - && resource.getProject().resources.configuration.propertiesFileSourceEncoding; - const encoding = nonAsciiEscaper.getEncodingFromAlias(propertiesFileSourceEncoding || "ISO-8859-1"); + const project = resource.getProject(); + let propertiesFileSourceEncoding = project && + project.resources && + project.resources.configuration && + project.resources.configuration.propertiesFileSourceEncoding; + + if (!propertiesFileSourceEncoding) { + if (project && ["0.1", "1.0", "1.1"].includes(project.specVersion)) { + // default encoding to "ISO-8859-1" for old specVersions + propertiesFileSourceEncoding = "ISO-8859-1"; + } else { + // default encoding to "UTF-8" for all projects starting with specVersion 2.0 + propertiesFileSourceEncoding = "UTF-8"; + } + } + const encoding = nonAsciiEscaper.getEncodingFromAlias(propertiesFileSourceEncoding); await nonAsciiEscaper({ resources: [resource.resource], options: { diff --git a/lib/processors/bootstrapHtmlTransformer.js b/lib/processors/bootstrapHtmlTransformer.js index c5dc7e0b0..9df539ee8 100644 --- a/lib/processors/bootstrapHtmlTransformer.js +++ b/lib/processors/bootstrapHtmlTransformer.js @@ -5,24 +5,26 @@ const cheerio = require("cheerio"); * Transforms the UI5 bootstrap of a HTML resource files. * * @module builder/processors/bootstrapHtmlTransformer - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed - * @param {Object} [parameters.options] Options - * @param {string} [parameters.options.src] Bootstrap "src" that should be used + * @param {object} parameters.options Options + * @param {string} parameters.options.src Bootstrap "src" that should be used * @returns {Promise} Promise resolving with the cloned resources */ -module.exports = function({resources, options}) { +module.exports = function({resources, options: {src}}) { async function processResource(resource) { const content = await resource.getString(); const $ = cheerio.load(content); const bootstrapScript = $("script#sap-ui-bootstrap"); if (bootstrapScript.length === 1) { - bootstrapScript.attr("src", options.src); + bootstrapScript.attr("src", src); resource.setString($.html()); } else if (bootstrapScript.length > 1) { - log.warn("Skipping bootstrap transformation. Found multiple bootstrap script tags with id=sap-ui-bootstrap."); + log.warn("Skipping bootstrap transformation. " + + "Found multiple bootstrap script tags with id=sap-ui-bootstrap."); } else { - log.warn("Skipping bootstrap transformation. Could not find bootstrap script tag with id=sap-ui-bootstrap."); + log.warn("Skipping bootstrap transformation. " + + "Could not find bootstrap script tag with id=sap-ui-bootstrap."); } return resource; } diff --git a/lib/processors/bundlers/flexChangesBundler.js b/lib/processors/bundlers/flexChangesBundler.js index 8f68ff3cc..3d7cea548 100644 --- a/lib/processors/bundlers/flexChangesBundler.js +++ b/lib/processors/bundlers/flexChangesBundler.js @@ -6,23 +6,86 @@ const resourceFactory = require("@ui5/fs").resourceFactory; * * @public * @alias module:@ui5/builder.processors.flexChangesBundler - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.pathPrefix Prefix for bundle path + * @param {string} parameters.options.hasFlexBundleVersion true if minUI5Version >= 1.73 than + * create flexibility-bundle.json * @returns {Promise} Promise resolving with flex changes bundle resources */ -module.exports = function({resources, options}) { +module.exports = function({resources, options: {pathPrefix, hasFlexBundleVersion}}) { + let bundleName = "changes-bundle.json"; + function sortByTimeStamp(a, b) { return a.creation > b.creation ? 1 : -1; } - function sortAndStringify(changesContent) { + /** + * bundle changes resource to json string + * + * @param {Array} changesContent Array of resources files + * @returns {string} Json sting of changes and control variants + */ + function sortAndStringifyInFlexFormat(changesContent) { changesContent = changesContent.sort(sortByTimeStamp); - changesContent = changesContent.map(function(change) { - return JSON.stringify(change); + const changes = []; + const variantDependentControlChanges = []; + const compVariants = []; + const variants = []; + const variantChanges = []; + const variantManagementChanges = []; + + changesContent.forEach(function(content) { + switch (content.fileType) { + case "change": + if (content.appDescriptorChange && (content.appDescriptorChange === "true" || + content.appDescriptorChange == true)) { + break; + } + if (content.variantReference && content.variantReference !== "") { + variantDependentControlChanges.push(content); + } else { + changes.push(content); + } + break; + case "variant": + compVariants.push(content); + break; + case "ctrl_variant": + variants.push(content); + break; + case "ctrl_variant_change": + variantChanges.push(content); + break; + case "ctrl_variant_management_change": + variantManagementChanges.push(content); + break; + } }); - return changesContent; + + if (!hasFlexBundleVersion && (compVariants.length != 0 || variants.length != 0 || variantChanges.length != 0 || + variantDependentControlChanges.length != 0 || variantManagementChanges.length != 0)) { + throw new Error( + "There are some control variant changes in the changes folder. This only works with a " + + "minUI5Version 1.73.0. Please update the minUI5Version in the manifest.json to 1.73.0 or higher"); + } + // create changes-bundle.json + if (!hasFlexBundleVersion) { + return JSON.stringify(changes); + } else { + bundleName = "flexibility-bundle.json"; + const newChangeFormat = { + changes, + compVariants, + variants, + variantChanges, + variantDependentControlChanges, + variantManagementChanges + }; + + return JSON.stringify(newChangeFormat); + } } return Promise.all(resources.map((resource) => { @@ -34,10 +97,10 @@ module.exports = function({resources, options}) { log.info("Changes collected. Number of changes: " + nNumberOfChanges); const result = []; if (nNumberOfChanges > 0) { - changesContent = sortAndStringify(changesContent); + changesContent = sortAndStringifyInFlexFormat(changesContent); result.push(resourceFactory.createResource({ - path: `${options.pathPrefix}/changes/changes-bundle.json`, - string: "[" + changesContent.join(",") + "]" + path: `${pathPrefix}/changes/${bundleName}`, + string: changesContent })); } return result; diff --git a/lib/processors/bundlers/manifestBundler.js b/lib/processors/bundlers/manifestBundler.js index abc7c6d03..03359d53b 100644 --- a/lib/processors/bundlers/manifestBundler.js +++ b/lib/processors/bundlers/manifestBundler.js @@ -26,8 +26,9 @@ class I18nResourceList { const normalizedDirectory = path.normalize(directory); if (!this.propertyFiles.has(normalizedDirectory)) { this.propertyFiles.set(normalizedDirectory, [resource]); + } else { + this.propertyFiles.get(normalizedDirectory).push(resource); } - this.propertyFiles.get(normalizedDirectory).push(resource); } /** @@ -46,22 +47,29 @@ class I18nResourceList { * * @alias module:@ui5/builder.processors.manifestBundler * @public - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.namespace Namespace of the project * @param {string} parameters.options.bundleName Name of the bundled zip file - * @param {string} parameters.options.propertiesExtension Extension name of the properties files + * @param {string} parameters.options.propertiesExtension Extension name of the properties files, e.g. ".properties" * @param {string} parameters.options.descriptor Descriptor name * @returns {Promise} Promise resolving with manifest bundle resources */ -module.exports = ({resources, options}) => { +module.exports = ({resources, options: {namespace, bundleName, propertiesExtension, descriptor}}) => { function getDescriptorI18nInfo(manifest) { const content = JSON.parse(manifest.content); - const i18nFullPath = content["sap.app"]["i18n"] || "i18n/i18n.properties"; + let i18nFullPath = content["sap.app"]["i18n"]; + // i18n section in sap.app can be either a string or an object with bundleUrl + if (typeof i18nFullPath === "object") { + i18nFullPath = i18nFullPath.bundleUrl; + } + if (!i18nFullPath) { + i18nFullPath = "i18n/i18n.properties"; + } return { path: path.join(path.dirname(manifest.path), path.dirname(i18nFullPath)), - rootName: path.basename(i18nFullPath, options.propertiesExtension) + rootName: path.basename(i18nFullPath, propertiesExtension) }; } @@ -70,7 +78,7 @@ module.exports = ({resources, options}) => { const basename = path.basename(resource.getPath()); return { name: basename, - isManifest: basename === options.descriptor, + isManifest: basename === descriptor, path: resource.getPath(), content: content }; @@ -100,11 +108,11 @@ module.exports = ({resources, options}) => { return archiveContent; }).then((archiveContent) => new Promise((resolve) => { const zip = new yazl.ZipFile(); - const rBasePath = new RegExp(`^/resources/${options.namespace}/`); + const rBasePath = new RegExp(`^/resources/${namespace}/`); archiveContent.forEach((content, path) => { if (!rBasePath.test(path)) { log.verbose(`Not bundling resource with path ${path} since it is not based on path ` + - `/resources/${options.namespace}/`); + `/resources/${namespace}/`); return; } // Remove base path. Absolute paths are not allowed in ZIP files @@ -113,9 +121,9 @@ module.exports = ({resources, options}) => { }); zip.end(); - const pathPrefix = "/resources/" + options.namespace + "/"; + const pathPrefix = "/resources/" + namespace + "/"; const res = resourceFactory.createResource({ - path: pathPrefix + options.bundleName, + path: pathPrefix + bundleName, stream: zip.outputStream }); resolve([res]); diff --git a/lib/processors/bundlers/moduleBundler.js b/lib/processors/bundlers/moduleBundler.js index 022ee847e..5da1507f4 100644 --- a/lib/processors/bundlers/moduleBundler.js +++ b/lib/processors/bundlers/moduleBundler.js @@ -1,45 +1,7 @@ const BundleBuilder = require("../../lbt/bundle/Builder"); -const Resource = require("../../lbt/resources/Resource"); -const ResourcePool = require("../../lbt/resources/ResourcePool"); +const LocatorResourcePool = require("../../lbt/resources/LocatorResourcePool"); const EvoResource = require("@ui5/fs").Resource; -function extractName(path) { - return path.slice( "/resources/".length); -} - -class LocatorResource extends Resource { - constructor(pool, resource) { - super(pool, extractName(resource.getPath()), null, resource.getStatInfo()); - this.resource = resource; - } - - buffer() { - return this.resource.getBuffer(); - } - - getProject() { - return this.resource._project; - } -} - -class LocatorResourcePool extends ResourcePool { - constructor() { - super(); - } - - prepare(resources) { - resources = resources.filter( (res) => !res.getStatInfo().isDirectory() ); - // console.log(resources.map($ => $.getPath())); - return Promise.all( - resources.map( - (resource) => this.addResource( new LocatorResource(this, resource) ) - ).filter( (followUp) => followUp ) - ); - // .then( () => { - // console.log(" found %d resources", this.size); - // }); - } -} /** * A ModuleBundleDefinitionSection specifies the embedding mode ('provided', 'raw', 'preload' or 'require') @@ -48,80 +10,113 @@ class LocatorResourcePool extends ResourcePool { * Module bundle section modes
*
    *
  • - * provided: A section of mode 'provided' defines a set of modules that should not be included in the bundle file itself, but - which should be assumed to be already loaded (or 'provided') by the environment into which the bundle module is loaded. + * provided: A section of mode 'provided' defines a set of modules that should not be included in + * the bundle file itself, but which should be assumed to be already loaded (or 'provided') by the environment into + * which the bundle module is loaded. *
  • *
  • - raw: A raw section determines the set of modules that should be embedded, - sorts them according to their dependencies and writes them out 1:1 without any transformation or wrapping (raw). Only JavaScript sources - can be embedded in a raw section. -
  • + * raw: A raw section determines the set of modules that should be embedded, sorts them according + * to their dependencies and writes them out 1:1 without any transformation or wrapping (raw). Only JavaScript + * sources can be embedded in a raw section. + * *
  • - preload: A preload section packages resources that should be stored in the preload cache in the client. - They can embed any textual resource type (JavaScript, XML, JSON and .properties files) that the bundling supports. - UI5 modules are wrapped into a 'sap.ui.predefine' call. Other JavaScript modules will be embedded into a 'jQuery.sap.registerPreload' call, unless the - asynchronous ui5loader is used. With the ui5loader 'sap.ui.require.preload' is used for other modules. -
  • + * preload: A preload section packages resources that should be stored in the preload cache in the + * client. They can embed any textual resource type (JavaScript, XML, JSON and .properties files) that the + * bundling supports. UI5 modules are wrapped into a 'sap.ui.predefine' call. Other JavaScript modules will be + * embedded into a 'jQuery.sap.registerPreload' call, unless the asynchronous ui5loader is used. With the + * ui5loader 'sap.ui.require.preload' is used for other modules. + * *
  • - require: A 'require' section is transformed into a sequence of jQuery.sap.require calls. The list will be resolved like an include pattern list - in any of the other sections and for each of the resolved modules, a jQuery.sap.require will be created. In case the ui5loader is available, 'sap.ui.requireSync' is used instead. -
  • + * require: A 'require' section is transformed into a sequence of jQuery.sap.require calls. The + * list will be resolved like an include pattern list in any of the other sections and for each of the resolved + * modules, a jQuery.sap.require will be created. In case the ui5loader is available, 'sap.ui.requireSync' is + * used instead. + * *
*

* * @public * @typedef {object} ModuleBundleDefinitionSection * @property {string} mode The embedding mode. Either 'provided', 'raw', 'preload' or 'require' - * @property {string[]} filters List of modules declared as glob patterns (resource name patterns) that should be in- or excluded. - * A pattern either contains of a trailing slash '/' or single '*' and double '**' asterisks which denote an arbitrary number of characters or folder names. - * Exludes should be marked with a leading exclamation mark '!'. The order of filters is relevant, a later exclusion overrides an earlier inclusion and vice versa. + * @property {string[]} filters List of modules declared as glob patterns (resource name patterns) that should be + * in- or excluded. + * A pattern either contains of a trailing slash '/' or single '*' and double '**' asterisks which denote an + * arbitrary number of characters or folder names. + * Exludes should be marked with a leading exclamation mark '!'. The order of filters is relevant, a later + * exclusion overrides an earlier inclusion and vice versa. * @example List of modules as glob patterns that should be in- or excluded * // Includes everything from "some/path/to/module/", * // but excludes the subfolder "some/path/to/module/to/be/excluded/" - * filters: - * - "some/path/to/module/" - * - "!some/path/to/module/to/be/excluded/" + * const section = { + * "filters": [ + * "some/path/to/module/", + * "!some/path/to/module/to/be/excluded/" + * ] + * }; * - * @property {boolean} [resolve=false] Whether (transitive) dependencies of modules that match the given filters should be resolved - * and added to the module set + * @property {boolean} [resolve=false] Whether (transitive) dependencies of modules that match the given filters + * should be resolved and added to the module set * @property {boolean} [resolveConditional=false] Whether conditional dependencies of modules should be resolved * and added to the module set for this section * @property {boolean} [renderer=false] Whether renderers for controls should be added to the module set - * @property {boolean} [declareRawModules=true] Whether raw modules should be declared after jQuery.sap.global became available. With the usage of the ui5loader, this flag should be set to 'false' + * @property {boolean} [declareRawModules=false] Whether raw modules should be declared after jQuery.sap.global + * became available. With the usage of the ui5loader, this flag should be set to 'false' * @property {boolean} [sort=true] Whether the modules should be sorted by their dependencies */ +/** + * Module bundle definition + * + * @public + * @typedef {object} ModuleBundleDefinition + * @property {string} name The module bundle name + * @property {string[]} [defaultFileTypes=[".js", ".fragment.xml", ".view.xml", ".properties", ".json"]] + * List of default file types to be included in the bundle + * @property {ModuleBundleDefinitionSection[]} sections List of module bundle definition sections. + */ + +/** + * Module bundle options + * + * @public + * @typedef {object} ModuleBundleOptions + * @property {boolean} [optimize=false] If set to 'true' the module bundle gets minified + * @property {boolean} [decorateBootstrapModule=false] If set to 'false', the module won't be decorated + * with an optimization marker + * @property {boolean} [addTryCatchRestartWrapper=false] Whether to wrap bootable module bundles with + * a try/catch to filter out "Restart" errors + * @property {boolean} [usePredefineCalls=false] If set to 'true', sap.ui.predefine is used for UI5 modules + * @property {number} [numberOfParts=1] The number of parts the module bundle should be splitted + * @property {boolean} [ignoreMissingModules=false] When searching for modules which are optional for further + * processing, do not throw in case they are missing + */ + /** * Legacy preload bundler. * * @public * @alias module:@ui5/builder.processors.moduleBundler - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources Resources - * @param {Object} parameters.options Options - * @param {Object} parameters.options.bundleDefinition Module bundle definition - * @param {string} parameters.options.bundleDefinition.name The module bundle name - * @param {string[]} [parameters.options.bundleDefinition.defaultFileTypes=[".js", ".fragment.xml", ".view.xml", ".properties", ".json"]] List of default file types to be included in the bundle - * @param {ModuleBundleDefinitionSection[]} parameters.options.bundleDefinition.sections List of module bundle definition sections. - * @param {Object} parameters.options.bundleOptions Module bundle options - * @param {boolean} [parameters.options.bundleOptions.optimize=false] If set to 'true' the module bundle gets minified - * @param {boolean} [parameters.options.bundleOptions.decorateBootstrapModule=true] If set to 'false', the module won't be decorated with an optimization marker - * @param {boolean} [parameters.options.bundleOptions.addTryCatchRestartWrapper=false] Whether to wrap bootable module bundles with a try/catch to filter out "Restart" errors - * @param {boolean} [parameters.options.bundleOptions.usePredefineCalls=false] If set to 'true', sap.ui.predefine is used for UI5 modules - * @param {number} [parameters.options.bundleOptions.numberOfParts=1] The number of parts the module bundle should be splitted + * @param {object} parameters.options Options + * @param {ModuleBundleDefinition} parameters.options.bundleDefinition Module bundle definition + * @param {ModuleBundleOptions} parameters.options.bundleOptions Module bundle options * @returns {Promise} Promise resolving with module bundle resources */ -module.exports = function({resources, options}) { +module.exports = function({resources, options: {bundleDefinition, bundleOptions}}) { // console.log("preloadBundler bundleDefinition:"); // console.log(JSON.stringify(options.bundleDefinition, null, 4)); - const pool = new LocatorResourcePool(); - const builder = new BundleBuilder(pool); + // TODO 3.0: Fix defaulting behavior, align with JSDoc + bundleOptions = bundleOptions || {optimize: true}; - const bundleOptions = options.bundleOptions || {optimize: true}; + const pool = new LocatorResourcePool({ + ignoreMissingModules: bundleOptions.ignoreMissingModules + }); + const builder = new BundleBuilder(pool); return pool.prepare( resources ). - then( () => builder.createBundle(options.bundleDefinition, bundleOptions) ). + then( () => builder.createBundle(bundleDefinition, bundleOptions) ). then( (results) => { let bundles; if (results instanceof Array) { @@ -130,13 +125,16 @@ module.exports = function({resources, options}) { bundles = [results]; } - return Promise.all(bundles.map(function({name, content, bundleInfo}) { - // console.log("creating bundle as '%s'", "/resources/" + name); - const resource = new EvoResource({ - path: "/resources/" + name, - string: content - }); - return resource; + return Promise.all(bundles.map((bundleObj) => { + if ( bundleObj ) { + const {name, content} = bundleObj; + // console.log("creating bundle as '%s'", "/resources/" + name); + const resource = new EvoResource({ + path: "/resources/" + name, + string: content + }); + return resource; + } })); }); }; diff --git a/lib/processors/debugFileCreator.js b/lib/processors/debugFileCreator.js index 992a59ae6..f1efd78b4 100644 --- a/lib/processors/debugFileCreator.js +++ b/lib/processors/debugFileCreator.js @@ -6,8 +6,10 @@ const util = require("util"); * * @public * @alias module:@ui5/builder.processors.debugFileCreator - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed + * @param {fs|module:@ui5/fs.fsInterface} parameters.fs Node fs or + * custom [fs interface]{@link module:resources/module:@ui5/fs.fsInterface} * @returns {Promise} Promise resolving with debug resources */ module.exports = function({resources, fs}) { diff --git a/lib/processors/jsdoc/apiIndexGenerator.js b/lib/processors/jsdoc/apiIndexGenerator.js index c3026557d..e311a6f41 100644 --- a/lib/processors/jsdoc/apiIndexGenerator.js +++ b/lib/processors/jsdoc/apiIndexGenerator.js @@ -1,5 +1,5 @@ const resourceFactory = require("@ui5/fs").resourceFactory; -const createIndex = require("./lib/create-api-index"); +const createIndex = require("./lib/createIndexFiles"); /** * Compiles API index resources from all api.json resources available in the given test resources directory @@ -9,7 +9,7 @@ const createIndex = require("./lib/create-api-index"); * * @public * @alias module:@ui5/builder.processors.apiIndexGenerator - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {string} parameters.versionInfoPath Path to sap-ui-version.json resource * @param {string} parameters.testResourcesRootPath Path to /test-resources root directory in the * given fs diff --git a/lib/processors/jsdoc/jsdocGenerator.js b/lib/processors/jsdoc/jsdocGenerator.js index 4c1d766c5..ada941458 100644 --- a/lib/processors/jsdoc/jsdocGenerator.js +++ b/lib/processors/jsdoc/jsdocGenerator.js @@ -10,33 +10,35 @@ const {resourceFactory} = require("@ui5/fs"); * * @public * @alias module:@ui5/builder.processors.jsdocGenerator - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {string} parameters.sourcePath Path of the source files to be processed * @param {string} parameters.targetPath Path to write any output files * @param {string} parameters.tmpPath Path to write temporary and debug files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @param {string} parameters.options.namespace Namespace to build (e.g. some/project/name) * @param {string} parameters.options.version Project version * @param {Array} [parameters.options.variants=["apijson"]] JSDoc variants to be built * @returns {Promise} Promise resolving with newly created resources */ -const jsdocGenerator = async function({sourcePath, targetPath, tmpPath, options} = {}) { - if (!sourcePath || !targetPath || !tmpPath || !options.projectName || !options.namespace || !options.version) { +const jsdocGenerator = async function( + {sourcePath, targetPath, tmpPath, options: {projectName, namespace, version, variants}} = {} +) { + if (!sourcePath || !targetPath || !tmpPath || !projectName || !namespace || !version) { throw new Error("[jsdocGenerator]: One or more mandatory parameters not provided"); } - if (!options.variants || options.variants.length === 0) { - options.variants = ["apijson"]; + if (!variants || variants.length === 0) { + variants = ["apijson"]; } const config = await jsdocGenerator._generateJsdocConfig({ targetPath, tmpPath, - namespace: options.namespace, - projectName: options.projectName, - version: options.version, - variants: options.variants + namespace, + projectName, + version, + variants }); const configPath = await jsdocGenerator._writeJsdocConfig(tmpPath, config); @@ -53,7 +55,7 @@ const jsdocGenerator = async function({sourcePath, targetPath, tmpPath, options} // create resources from the output files return Promise.all([ - fsTarget.byPath(`/test-resources/${options.namespace}/designtime/api.json`) + fsTarget.byPath(`/test-resources/${namespace}/designtime/api.json`) // fsTarget.byPath(`/libraries/${options.projectName}.js`) ]).then((res) => res.filter(($)=>$)); }; @@ -63,11 +65,12 @@ const jsdocGenerator = async function({sourcePath, targetPath, tmpPath, options} * Generate jsdoc-config.json content * * @private - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {string} parameters.targetPath Path to write any output files * @param {string} parameters.tmpPath Path to write temporary and debug files * @param {string} parameters.projectName Project name * @param {string} parameters.version Project version + * @param {string} parameters.namespace Namespace to use (e.g. some/project/name) * @param {Array} parameters.variants JSDoc variants to be built * @returns {string} jsdoc-config.json content string */ @@ -131,7 +134,7 @@ async function writeJsdocConfig(targetDirPath, config) { * Execute JSDoc build by spawning JSDoc as an external process * * @private - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {string} parameters.sourcePath Project resources (input for JSDoc generation) * @param {string} parameters.configPath Full path to jsdoc-config.json file * @returns {Promise} diff --git a/lib/processors/jsdoc/lib/create-api-index.js b/lib/processors/jsdoc/lib/createIndexFiles.js similarity index 80% rename from lib/processors/jsdoc/lib/create-api-index.js rename to lib/processors/jsdoc/lib/createIndexFiles.js index a2186a8e5..f258e16a6 100644 --- a/lib/processors/jsdoc/lib/create-api-index.js +++ b/lib/processors/jsdoc/lib/createIndexFiles.js @@ -1,7 +1,7 @@ /* * Node script to create cross-library API index files for use in the UI5 SDKs. * - * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company. + * (c) Copyright 2009-2020 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ @@ -24,7 +24,7 @@ const log = (function() { } }()); -function process(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetFileDeprecated, targetFileExperimental, targetFileSince, options) { +function createIndexFiles(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetFileDeprecated, targetFileExperimental, targetFileSince, options) { const fs = options && options.fs || require("fs"); const returnOutputFiles = options && !!options.returnOutputFiles; @@ -248,13 +248,12 @@ function process(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetF let aTree = []; // Filter out black list libraries - symbols = symbols.filter(({lib}) => ["sap.ui.demokit", "sap.ui.documentation"].indexOf(lib) === -1); + symbols = symbols.filter(({lib}) => ["sap.ui.documentation"].indexOf(lib) === -1); // Create treeName and displayName symbols.forEach(oSymbol => { oSymbol.treeName = oSymbol.name.replace(/^module:/, "").replace(/\//g, "."); oSymbol.displayName = oSymbol.treeName.split(".").pop(); - oSymbol.bIsDeprecated = !!oSymbol.deprecated; }); // Create missing - virtual namespaces @@ -269,7 +268,7 @@ function process(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetF displayName: sPart, lib: oSymbol.lib, kind: "namespace", - bIsDeprecated: false // Virtual namespace can't be deprecated + visibility: "public" // Virtual namespace are always public }); } }); @@ -325,12 +324,18 @@ function process(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetF return 0; }); + // walk the tree *from bottom to top* + // in order to detect all parent nodes + // that should be marked as content-deprecated + // because their children are explicitly deprecated + toChildrenFirstArray(aTree).forEach(markDeprecatedNodes); + // Clean tree - keep file size down function cleanTree (oSymbol) { delete oSymbol.treeName; delete oSymbol.parent; - if (oSymbol.children) { - oSymbol.children.forEach(o => cleanTree(o)); + if (oSymbol.nodes) { + oSymbol.nodes.forEach(o => cleanTree(o)); } } aTree.forEach(o => cleanTree(o)); @@ -338,6 +343,68 @@ function process(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetF return aTree; } + /** + * Creates an array of all tree nodes, + * where the child nodes precede the parent nodes + * @param aTree + * @returns {Array} + */ + function toChildrenFirstArray(aTree) { + var aChildrenFirst = []; + function addToLeafsFirst(node) { + if (node.nodes) { + node.nodes.forEach(function(child) { + addToLeafsFirst(child); + }); + } + aChildrenFirst.push(node); + } + aTree.forEach(function(parent) { + addToLeafsFirst(parent); + }); + return aChildrenFirst; + } + + /** + * Sets the bAllContentDeprecated flag of each symbol + * + * The bAllContentDeprecated flag differs from the already existing deprecated flag + * in the following respect: + * + * 1) if a node is deprecated => all its children should be marked as bAllContentDeprecated + * (even if not explicitly deprecated in their JSDoc) + * 2) if all children of the node are deprecated => that node should also be marked as bAllContentDeprecated + * (even if not explicitly deprecated in its JSDoc) + * 3) if a node is explicitly deprecated in its JSDoc => it should also be marked as bAllContentDeprecated + * (for consistency) + * + * @param oSymbol + */ + function markDeprecatedNodes(oSymbol) { + // 1. If the symbol is deprecated all content in it should be also deprecated + if (oSymbol.deprecated) { + // 2. If all content in the symbol is deprecated, flag should explicitly be passed to its child nodes. + propagateFlags(oSymbol, { bAllContentDeprecated: true }); + } else { + // 3. If all children are deprecated, then the parent is marked as content-deprecated + oSymbol.bAllContentDeprecated = !!oSymbol.nodes && oSymbol.nodes.every(node => node.bAllContentDeprecated); + } + } + + /** + * Merges the set of flags from oFlags into the given oSymbol + * @param oSymbol + * @param oFlags + */ + function propagateFlags(oSymbol, oFlags) { + Object.assign(oSymbol, oFlags); + if (oSymbol.nodes) { + oSymbol.nodes.forEach(node => { + propagateFlags(node, oFlags); + }) + } + } + function createOverallIndex() { let version = "0.0.0"; const filesToReturn = {}; @@ -449,4 +516,4 @@ function process(versionInfoFile, unpackedTestresourcesRoot, targetFile, targetF } -module.exports = process; +module.exports = createIndexFiles; diff --git a/lib/processors/jsdoc/lib/transform-apijson-for-sdk.js b/lib/processors/jsdoc/lib/transformApiJson.js similarity index 81% rename from lib/processors/jsdoc/lib/transform-apijson-for-sdk.js rename to lib/processors/jsdoc/lib/transformApiJson.js index c8e27a71a..af8585e20 100644 --- a/lib/processors/jsdoc/lib/transform-apijson-for-sdk.js +++ b/lib/processors/jsdoc/lib/transformApiJson.js @@ -1,7 +1,7 @@ /* * Node script to preprocess api.json files for use in the UI5 SDKs. * - * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company. + * (c) Copyright 2009-2020 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ @@ -10,7 +10,7 @@ const cheerio = require("cheerio"); const path = require('path'); const log = (function() { try { - return require("@ui5/logger").getLogger("builder:processors:jsdoc:transform-apijson-for-sdk"); + return require("@ui5/logger").getLogger("builder:processors:jsdoc:transformApiJson"); } catch (error) { /* eslint-disable no-console */ return { @@ -132,14 +132,24 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, // Attach children info symbols.forEach(oSymbol => { if (oSymbol.parent) { - let oParent = symbols.find(({treeName}) => treeName === oSymbol.parent); + let oParent = symbols.find(({treeName}) => treeName === oSymbol.parent), + oNode; if (!oParent.nodes) oParent.nodes = []; - oParent.nodes.push({ + + oNode = { name: oSymbol.displayName, - description: formatters._preProcessLinksInTextBlock(oSymbol.description), - href: "#/api/" + encodeURIComponent(oSymbol.name) - }); + description: formatters._preProcessLinksInTextBlock( + extractFirstSentence(oSymbol.description) + ), + href: "api/" + encodeURIComponent(oSymbol.name) + }; + + if (oSymbol.deprecated) { + oNode.deprecated = true; + } + + oParent.nodes.push(oNode); } }); @@ -306,7 +316,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, // Link Enabled if (oSymbol.kind !== "enum" && !isBuiltInType(oProperty.type) && possibleUI5Symbol(oProperty.type)) { oProperty.linkEnabled = true; - oProperty.href = "#/api/" + oProperty.type.replace("[]", ""); + oProperty.href = "api/" + oProperty.type.replace("[]", ""); } // Keep file size in check @@ -315,7 +325,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, } if (oSymbol.kind === "enum" || oProperty.type === "undefined") { - delete oProperty.type; + delete oProperty.type; } }); @@ -390,7 +400,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, oAggregation.description = formatters.formatDescription(oAggregation.description, oAggregation.deprecated.text, oAggregation.deprecated.since); } else { - oAggregation.description = formatters.formatDescription(oAggregation.description); + oAggregation.description = formatters.formatDescriptionSince(oAggregation.description, oAggregation.since); } // Link enabled @@ -424,13 +434,39 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, oAssociation.description = formatters.formatDescription(oAssociation.description, oAssociation.deprecated.text, oAssociation.deprecated.since); } else { - oAssociation.description = formatters.formatDescription(oAssociation.description); + oAssociation.description = formatters.formatDescriptionSince(oAssociation.description, oAssociation.since); } }); } // Events if (oMeta.events) { + + oMeta.events.forEach(oEvent => { + let aParams = oEvent.parameters; + + aParams && Object.keys(aParams).forEach(sParam => { + let sSince = aParams[sParam].since; + let oDeprecated = aParams[sParam].deprecated; + let oEvtInSymbol = oSymbol.events.find(e => e.name === oEvent.name); + let oParamInSymbol = oEvtInSymbol && oEvtInSymbol.parameters[0] && + oEvtInSymbol.parameters[0].parameterProperties && + oEvtInSymbol.parameters[0].parameterProperties.getParameters && + oEvtInSymbol.parameters[0].parameterProperties.getParameters.parameterProperties && + oEvtInSymbol.parameters[0].parameterProperties.getParameters.parameterProperties[sParam]; + + if (typeof oParamInSymbol === 'object' && oParamInSymbol !== null) { + if (sSince) { + oParamInSymbol.since = sSince; + } + + if (oDeprecated) { + oParamInSymbol.deprecated = oDeprecated; + } + } + }) + }); + // We don't need event's data from the UI5-metadata for now. Keep file size in check delete oMeta.events; } @@ -506,13 +542,15 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, } // Description - if (oParameter.deprecated) { - oParameter.description = formatters.formatDescription(oParameter.description, - oParameter.deprecated.text, oParameter.deprecated.since); - } else { - oParameter.description = formatters.formatDescription(oParameter.description); + if (oParameter.description) { + oParameter.description = formatters.formatDescriptionSince(oParameter.description, oParameter.since); } + // Deprecated + if (oParameter.deprecated) { + oParameter.deprecatedText = formatters.formatDeprecated(oParameter.deprecated.since, + oParameter.deprecated.text); + } }); } @@ -533,8 +571,8 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, oMethod.name = formatters.formatEntityName(oMethod.name, oSymbol.name, oMethod.static); // Link - oMethod.href = "#/api/" + encodeURIComponent(oSymbol.name) + - "/methods/" + encodeURIComponent(oMethod.name); + oMethod.href = "api/" + oSymbol.name + + "#methods/" + oMethod.name; } formatters.formatReferencesInDescription(oMethod); @@ -569,7 +607,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, // Link Enabled if (!isBuiltInType(oType.value) && possibleUI5Symbol(oType.value)) { oType.linkEnabled = true; - oType.href = "#/api/" + oType.value.replace("[]", ""); + oType.href = "api/" + oType.value.replace("[]", ""); } }); @@ -601,7 +639,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, // Link Enabled if (!isBuiltInType(oType.value)) { - oType.href = "#/api/" + encodeURIComponent(oType.value.replace("[]", "")); + oType.href = "api/" + oType.value.replace("[]", ""); oType.linkEnabled = true; } @@ -682,6 +720,13 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, return oChainObject; }; + function extractFirstSentence(sHTML) { + const rRegExp = /^.*?[\.!\?](?:\s|$)/; + const aMatch = rRegExp.exec(sHTML); + + return aMatch !== null ? aMatch[0] : sHTML; + } + function getDependencyLibraryFilesList(oChainObject) { // if vDependencyAPIFiles is an array, it contains the file paths of api.json files if ( Array.isArray(vDependencyAPIFiles) ) { @@ -695,7 +740,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, let aFiles = []; aItems.forEach(sItem => { aFiles.push(path.join(vDependencyAPIFiles, sItem)); - }) + }); oChainObject.aDependentLibraryFiles = aFiles; } oResolve(oChainObject); // We don't fail if no dependency library files are available @@ -984,11 +1029,13 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, * @returns string - the formatted text */ formatAnnotationNamespace: function (namespace) { - var result, - aNamespaceParts = namespace.split("."); + var aNamespaceParts = namespace.split("."), + result, target, text; if (aNamespaceParts[0] === "Org" && aNamespaceParts[1] === "OData") { - result = '' + namespace + ''; + target = this.ANNOTATIONS_NAMESPACE_LINK + namespace + ".xml"; + text = namespace; + result = this.handleExternalUrl(target, text); } else { result = namespace; } @@ -1254,341 +1301,339 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles, // Check if the external domain is SAP hosted let bSAPHosted = /^https?:\/\/(?:www.)?[\w.]*(?:sap|hana\.ondemand|sapfioritrial)\.com/.test(sTarget); - return `${sText} + return `${sText} `; }, - /** - * Discover possible target type by looking at symbols from own and depending libraries - * @param {string} target - * @param {object} self - * @param {object} ownLibrary - * @param {object} dependencyLibs - * @param {boolean} module - * @returns {string} - */ - createLinkFromTargetType: function ({className, methodName, target, self, ownLibrary, dependencyLibs, text}) { - let sResult; + /** + * Discover possible target type by looking at symbols from own and depending libraries + * @param {string} target + * @param {object} self + * @param {object} ownLibrary + * @param {object} dependencyLibs + * @param {boolean} module + * @returns {string} + */ + createLinkFromTargetType: function ({className, methodName, target, self, ownLibrary, dependencyLibs, text}) { + let sResult; - function searchInSymbol(oSymbol) { - function findProperty(oEntity, sName, sTarget) { - if (!oEntity || !oEntity.properties) { - return; + function searchInSymbol(oSymbol) { + function findProperty(oEntity, sName, sTarget) { + if (!oEntity || !oEntity.properties) { + return; + } + return oEntity.properties.find(({name}) => name === sName || name === sTarget); } - return oEntity.properties.find(({name}) => name === sName || name === sTarget); - } - function findMethod(oEntity, sName, sTarget) { - if (!oEntity || !oEntity.methods) { - return; + function findMethod(oEntity, sName, sTarget) { + if (!oEntity || !oEntity.methods) { + return; + } + return oEntity.methods.find(({name}) => name === sName || name === sTarget); } - return oEntity.methods.find(({name}) => name === sName || name === sTarget); - } - function findEvent(oEntity, sName) { - if (!oEntity || !oEntity.events) { - return; + function findEvent(oEntity, sName) { + if (!oEntity || !oEntity.events) { + return; + } + return oEntity.events.find(({name}) => name === sName); } - return oEntity.events.find(({name}) => name === sName); - } - if (oSymbol.name === target) { - sResult = this.createLink({ - name: oSymbol.name, - text: text - }); - return true; - } - if (oSymbol.name === className) { - let oProperty = findProperty(oSymbol, methodName, target); - if (oProperty) { + if (oSymbol.name === target) { sResult = this.createLink({ - name: oProperty.name, + name: oSymbol.name, text: text }); return true; } - let oMethod = findMethod(oSymbol, methodName, target); - if (oMethod) { - sResult = this.createLink({ - name: oMethod.static ? target : oMethod.name, - type: "methods", - text: text, - className: className - }); - return true; - } + if (oSymbol.name === className) { + let oProperty = findProperty(oSymbol, methodName, target); + if (oProperty) { + sResult = this.createLink({ + name: className, + text: text + }); + return true; + } + let oMethod = findMethod(oSymbol, methodName, target); + if (oMethod) { + sResult = this.createLink({ + name: oMethod.static ? target : oMethod.name, + type: "methods", + text: text, + className: className + }); + return true; + } - let oEvent = findEvent(oSymbol, methodName); - if (oEvent) { - sResult = this.createLink({ - name: oEvent.name, - type: "events", - text: text, - className: className - }); - return true; + let oEvent = findEvent(oSymbol, methodName); + if (oEvent) { + sResult = this.createLink({ + name: oEvent.name, + type: "events", + text: text, + className: className + }); + return true; + } } - } - - return false; - } - // Self link - if (self.name === target) { - return this.createLink({ - name: target, - text: text - }); - } + return false; + } - // Own methods search - if (self.name === className && self.methods) { - let oResult = self.methods.find(({name}) => name === methodName); - if (oResult) { + // Self link + if (self.name === target) { return this.createLink({ - name: oResult.static ? [self.name, oResult.name].join(".") : oResult.name, - type: "methods", - className: className, - text: text, - local: true + name: target, + text: text }); } - } - // Local library symbols - ownLibrary.symbols.find(oSymbol => { - return searchInSymbol.call(this, oSymbol); - }); - - if (sResult) return sResult; - - // Dependent library symbols - dependencyLibs && Object.keys(dependencyLibs).find(sLib => { - if (sLib === target) { - sResult = this.createLink({ - name: sLib, - text: text - }); - return true; + // Own methods search + if (self.name === className && self.methods) { + let oResult = self.methods.find(({name}) => name === methodName); + if (oResult) { + return this.createLink({ + name: oResult.static ? [self.name, oResult.name].join(".") : oResult.name, + type: "methods", + className: className, + text: text, + local: true + }); + } } - return dependencyLibs[sLib].find(oSymbol => { + + // Local library symbols + ownLibrary.symbols.find(oSymbol => { return searchInSymbol.call(this, oSymbol); }); - }); - return sResult; - }, + if (sResult) return sResult; - /** - * Creates a html link - * @param {string} name - * @param {string} type - * @param {string} className - * @param {string} [text=name] by default if no text is provided the name will be used - * @param {boolean} [local=false] - * @param {string} [hrefAppend=""] - * @returns {string} link - */ - createLink: function ({name, type, className, text=name, local=false, hrefAppend=""}) { - let sLink; + // Dependent library symbols + dependencyLibs && Object.keys(dependencyLibs).find(sLib => { + if (sLib === target) { + sResult = this.createLink({ + name: sLib, + text: text + }); + return true; + } + let oLib = dependencyLibs[sLib]; + return oLib && oLib.find(oSymbol => { + return searchInSymbol.call(this, oSymbol); + }); + }); - // handling module's - if (className !== undefined && (/^module:/.test(name) || /^module:/.test(className))) { - name = name.replace(/^module:/, ""); - } + return sResult; + }, - name = encodeURIComponent(name); - className = encodeURIComponent(className); + /** + * Creates a html link + * @param {string} name + * @param {string} type + * @param {string} className + * @param {string} [text=name] by default if no text is provided the name will be used + * @param {boolean} [local=false] + * @param {string} [hrefAppend=""] + * @returns {string} link + */ + createLink: function ({name, type, className, text=name, local=false, hrefAppend=""}) { + let sLink; - // Build the link - sLink = type ? `${className}/${type}/${name}` : name; + // handling module's + if (className !== undefined && (/^module:/.test(name) || /^module:/.test(className))) { + name = name.replace(/^module:/, ""); + } - if (hrefAppend) { - sLink += hrefAppend; - } + // Build the link + sLink = type ? `${className}#${type}/${name}` : name; - if (local) { - return `${text}`; - } + if (hrefAppend) { + sLink += hrefAppend; + } + + if (local) { + return `${text}`; + } - return `${text}`; - }, + return `${text}`; + }, /** * Pre-process links in text block * @param {string} sText text block - * @param {boolean} bSkipParagraphs skip paragraphs + * @param {boolean} bSkipParagraphs skip paragraphs * @returns {string} processed text block * @private */ _preProcessLinksInTextBlock: function (sText, bSkipParagraphs) { - let oSelf = this._oTopicData, - oOwnLibrary = this._oOwnLibrary, - oDependencyLibs = oChainObject.oDependentAPIs, + let oSelf = this._oTopicData, + oOwnLibrary = this._oOwnLibrary, + oDependencyLibs = oChainObject.oDependentAPIs, oOptions = { - linkFormatter: function (sTarget, sText) { - let aMatch, - aTarget; + linkFormatter: function (sTarget, sText) { + let aMatch, + aTarget; - // keep the full target in the fallback text - sText = sText || sTarget; + // keep the full target in the fallback text + sText = sText || sTarget; // If the link has a protocol, do not modify, but open in a new window - if (/:\/\//.test(sTarget)) { - return this.handleExternalUrl(sTarget, sText); + if (/:\/\//.test(sTarget)) { + return this.handleExternalUrl(sTarget, sText); } - // topic:xxx Topic - aMatch = sTarget.match(/^topic:(\w{32})$/); - if (aMatch) { - return '' + sText + ''; - } + // topic:xxx Topic + aMatch = sTarget.match(/^topic:(\w{32})$/); + if (aMatch) { + return '' + sText + ''; + } - // sap.x.Xxx.prototype.xxx - In case of prototype we have a link to method - aMatch = sTarget.match(/([a-zA-Z0-9.$_]+?)\.prototype\.([a-zA-Z0-9.$_]+)$/); + // sap.x.Xxx.prototype.xxx - In case of prototype we have a link to method + aMatch = sTarget.match(/([a-zA-Z0-9.$_]+?)\.prototype\.([a-zA-Z0-9.$_]+)$/); if (aMatch) { - return this.createLink({ - name: aMatch[2], - type: "methods", - className: aMatch[1], - text: sText - }); - } + return this.createLink({ + name: aMatch[2], + type: "methods", + className: aMatch[1], + text: sText + }); + } - // Heuristics: Extend is always a static method - // sap.x.Xxx.extend - // module:sap/x/Xxx.extend - aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+?)\.extend$/); - if (aMatch) { - let [, sModule, sClass] = aMatch; - return this.createLink({ - name: sTarget.replace(/^module:/, ""), - type: "methods", - className: (sModule ? sModule : "") + sClass, - text: sText - }); - } + // Heuristics: Extend is always a static method + // sap.x.Xxx.extend + // module:sap/x/Xxx.extend + aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+?)\.extend$/); + if (aMatch) { + let [, sModule, sClass] = aMatch; + return this.createLink({ + name: sTarget.replace(/^module:/, ""), + type: "methods", + className: (sModule ? sModule : "") + sClass, + text: sText + }); + } - // Constructor links are handled in special manner by the SDK - // sap.x.Xxx.constructor - // sap.x.Xxx#constructor - // module:sap/x/Xxx.constructor - // #constructor - aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+?)?[\.#]constructor$/i); - if (aMatch) { - let [, sModule, sClass] = aMatch, - sName; - - if (sClass) { - sName = (sModule ? sModule : "") + sClass; - } else { - sName = oSelf.name - } + // Constructor links are handled in special manner by the SDK + // sap.x.Xxx.constructor + // sap.x.Xxx#constructor + // module:sap/x/Xxx.constructor + // #constructor + aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+?)?[\.#]constructor$/i); + if (aMatch) { + let [, sModule, sClass] = aMatch, + sName; - return this.createLink({ - name: sName, - hrefAppend: "/constructor", - text: sText - }); - } + if (sClass) { + sName = (sModule ? sModule : "") + sClass; + } else { + sName = oSelf.name + } - // #.setText - local static method - // #setText - local instance method - // #.setText.from - local nested method - aMatch = sTarget.match(/^#(\.)?([a-zA-Z0-9.$_]+)$/); - if (aMatch) { - return this.createLink({ - name: aMatch[1] ? `${oSelf.name}.${aMatch[2]}` : aMatch[2], - type: "methods", - className: oSelf.name, - local: true, - text: sText - }); - } + return this.createLink({ + name: sName, + hrefAppend: "#constructor", + text: sText + }); + } - // #event:press - local event - aMatch = sTarget.match(/^#event:([a-zA-Z0-9$_]+)$/); - if (aMatch) { - return this.createLink({ - name: aMatch[1], - type: "events", - className: oSelf.name, - local: true, - text: sText - }); - } - // Event links - // sap.m.Button#event:press - // sap.m.Button.event:press - // module:sap/m/Button.event:press - // module:sap/m/Button#event:press - aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+?)[.#]event:([a-zA-Z0-9$_]+)$/); - if (aMatch) { - let [, sModule, sClass, sEvent] = aMatch; - return this.createLink({ - name: sEvent, - type: "events", - className: (sModule ? sModule : "") + sClass, - text: sText - }); - } + // #.setText - local static method + // #setText - local instance method + // #.setText.from - local nested method + aMatch = sTarget.match(/^#(\.)?([a-zA-Z0-9.$_]+)$/); + if (aMatch) { + return this.createLink({ + name: aMatch[1] ? `${oSelf.name}.${aMatch[2]}` : aMatch[2], + type: "methods", + className: oSelf.name, + local: true, + text: sText + }); + } - // sap.m.Button#setText - instance method - // module:sap/m/Button#setText - aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+)#([a-zA-Z0-9.$_]+)$/); - if (aMatch) { - let [, sModule, sClass, sMethod] = aMatch; - return this.createLink({ - name: sMethod, - type: "methods", - className: (sModule ? sModule : "") + sClass, - text: sText - }); - } + // #event:press - local event + aMatch = sTarget.match(/^#event:([a-zA-Z0-9$_]+)$/); + if (aMatch) { + return this.createLink({ + name: aMatch[1], + type: "events", + className: oSelf.name, + local: true, + text: sText + }); + } + // Event links + // sap.m.Button#event:press + // sap.m.Button.event:press + // module:sap/m/Button.event:press + // module:sap/m/Button#event:press + aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+?)[.#]event:([a-zA-Z0-9$_]+)$/); + if (aMatch) { + let [, sModule, sClass, sEvent] = aMatch; + return this.createLink({ + name: sEvent, + type: "events", + className: (sModule ? sModule : "") + sClass, + text: sText + }); + } - // Unresolved type - try to discover target type - // sap.x.Xxx.xxx - // module:sap/x/Xxx.xxx - if (/^(?:module:)?([a-zA-Z0-9.$_\/]+?)\.([a-zA-Z0-9$_]+)$/.test(sTarget)) { - let [,sClass, sName] = sTarget.match(/^((?:module:)?[a-zA-Z0-9.$_\/]+?)\.([a-zA-Z0-9$_]+)$/), - sResult = this.createLinkFromTargetType({ - className: sClass, - methodName: sName, + // sap.m.Button#setText - instance method + // module:sap/m/Button#setText + aMatch = sTarget.match(/^(module:)?([a-zA-Z0-9.$_\/]+)#([a-zA-Z0-9.$_]+)$/); + if (aMatch) { + let [, sModule, sClass, sMethod] = aMatch; + return this.createLink({ + name: sMethod, + type: "methods", + className: (sModule ? sModule : "") + sClass, + text: sText + }); + } + + // Unresolved type - try to discover target type + // sap.x.Xxx.xxx + // module:sap/x/Xxx.xxx + if (/^(?:module:)?([a-zA-Z0-9.$_\/]+?)\.([a-zA-Z0-9$_]+)$/.test(sTarget)) { + let [,sClass, sName] = sTarget.match(/^((?:module:)?[a-zA-Z0-9.$_\/]+?)\.([a-zA-Z0-9$_]+)$/), + sResult = this.createLinkFromTargetType({ + className: sClass, + methodName: sName, + target: sTarget, + self: oSelf, + ownLibrary: oOwnLibrary, + dependencyLibs: oDependencyLibs, + text: sText + }); + if (sResult) { + return sResult; + } + } + + // Possible nested functions discovery - currently we do this only for regular symbols + aTarget = sTarget.split("."); + if (aTarget.length >= 3) { + let sResult = this.createLinkFromTargetType({ + methodName: aTarget.splice(-2).join("."), + className: aTarget.join("."), target: sTarget, self: oSelf, ownLibrary: oOwnLibrary, dependencyLibs: oDependencyLibs, text: sText }); - if (sResult) { - return sResult; - } - } + if (sResult) { + return sResult; + } + } - // Possible nested functions discovery - currently we do this only for regular symbols - aTarget = sTarget.split("."); - if (aTarget.length >= 3) { - let sResult = this.createLinkFromTargetType({ - methodName: aTarget.splice(-2).join("."), - className: aTarget.join("."), - target: sTarget, - self: oSelf, - ownLibrary: oOwnLibrary, - dependencyLibs: oDependencyLibs, + // Possible forward reference - we will treat them as symbol link + return this.createLink({ + name: sTarget, text: sText }); - if (sResult) { - return sResult; - } - } - - // Possible forward reference - we will treat them as symbol link - return this.createLink({ - name: sTarget, - text: sText - }); }.bind(this) }; @@ -1749,8 +1794,8 @@ title="Information published on ${bSAPHosted ? '' : 'non '}SAP site" class="sapU // Extract first found UX Guidelines link as primary oSymbol.uxGuidelinesLink = UX_GUIDELINES_BASE_URL + sTarget; oSymbol.uxGuidelinesLinkText = sTargetName ? sTargetName : oSymbol.basename; - bUXGuidelinesLinkFound = true; - return; + bUXGuidelinesLinkFound = true; + return; } else { // BCP: 1870155880 - Every consecutive "fiori:" link should be handled as a normal link sReference = "{@link " + UX_GUIDELINES_BASE_URL + sTarget + (sTargetName ? " " + sTargetName : "") + "}"; @@ -1978,17 +2023,3 @@ title="Information published on ${bSAPHosted ? '' : 'non '}SAP site" class="sapU module.exports = transformer; -// auto execute the transformer, if this module is the executed script (not used in grunt tooling) -if ( process.argv.length > 1 && /transform-apijson-for-sdk.js$/.test(process.argv[1]) ) { - - let sInputFile = process.argv[2]; - let sOutputFile = process.argv[3]; - let sLibraryFile = process.argv[4]; - let sAPIJSonDependencyDir = process.argv[5]; - - transformer(sInputFile, sOutputFile, sLibraryFile, sAPIJSonDependencyDir) - .catch(oError => { - log.error(oError); - }); - -} diff --git a/lib/processors/jsdoc/lib/ui5/plugin.js b/lib/processors/jsdoc/lib/ui5/plugin.js index 0cba05cf7..1f5eef9dd 100644 --- a/lib/processors/jsdoc/lib/ui5/plugin.js +++ b/lib/processors/jsdoc/lib/ui5/plugin.js @@ -1,7 +1,7 @@ /* * JSDoc3 plugin for UI5 documentation generation. * - * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company. + * (c) Copyright 2009-2020 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ @@ -56,7 +56,7 @@ var Syntax = require('jsdoc/src/syntax').Syntax; var Doclet = require('jsdoc/doclet').Doclet; var fs = require('jsdoc/fs'); var path = require('jsdoc/path'); -var pluginConfig = (env.conf && env.conf.templates && env.conf.templates.ui5) || {}; +var pluginConfig = (env.conf && env.conf.templates && env.conf.templates.ui5) || env.opts.sapui5 || {}; /* ---- global vars---- */ @@ -99,7 +99,7 @@ var currentProgram; * have a 'module' and optionally a 'path' value. In that case, the local name represents an AMD * module import or a shortcut derived from such an import. * - * See {@link getREsolvedObjectName} how the knowledge about locale names is used. + * See {@link getResolvedObjectName} how the knowledge about locale names is used. * * @type {{name:string,resource:string,module:string,localName:Object}} */ @@ -117,6 +117,17 @@ var currentSource; */ var classInfos = Object.create(null); +/** + * Map of enum value objects keyed by a unqiue enum ID. + * + * When the AST visitor detects an object literal that might be an enum, it cannot easily determine + * the name of the enum. Therefore, the collected enum values are stored in this map keyed by a + * unique ID derived from the key set of the (potential) enum (ID = sorted key set, joined with '|'). + * + * In the parseComplete phase, the found values are merged into enum symbols (as detected by JSDoc). + */ +var enumValues = Object.create(null); + /** * */ @@ -281,7 +292,7 @@ function analyzeModuleDefinition(node) { /** * Searches the given body for variable declarations that can be evaluated statically, - * either because they refer to known AMD modukle imports (e.g. shortcut varialbes) + * either because they refer to known AMD module imports (e.g. shortcut variables) * or because they have a (design time) constant value. * * @param {ASTNode} body AST node of a function body that shall be searched for shortcuts @@ -494,6 +505,19 @@ function isProbingRequireCall(node) { ); } +function isPotentialEnum(node) { + if ( node == null || node.type !== Syntax.ObjectExpression ) { + return false; + } + return node.properties.every(function(prop) { + return isCompileTimeConstant(prop.value); + }); +} + +function isCompileTimeConstant(node) { + return node && node.type === Syntax.Literal; +} + function getObjectName(node) { if ( node.type === Syntax.MemberExpression && !node.computed && node.property.type === Syntax.Identifier ) { var prefix = getObjectName(node.object); @@ -685,7 +709,9 @@ function collectClassInfo(extendCall, classDoclet) { events : {}, methods : {}, annotations : {}, - designtime: false + designtime: false, + stereotype: null, + metadataClass: undefined }; function upper(n) { @@ -712,6 +738,17 @@ function collectClassInfo(extendCall, classDoclet) { } } + if ( extendCall.arguments.length > 2 ) { + // new class defines its own metadata class type + var metadataClass = getResolvedObjectName(extendCall.arguments[2]); + if ( metadataClass ) { + oClassInfo.metadataClass = getResolvedObjectName(extendCall.arguments[2]); + debug("found metadata class name '" + oClassInfo.metadataClass + "'"); + } else { + error("cannot understand metadata class parameter (AST node type '" + extendCall.arguments[2] + "')"); + } + } + var classInfoNode = extendCall.arguments[1]; var classInfoMap = createPropertyMap(classInfoNode); if ( classInfoMap && classInfoMap.metadata && classInfoMap.metadata.value.type !== Syntax.ObjectExpression ) { @@ -724,6 +761,9 @@ function collectClassInfo(extendCall, classDoclet) { debug(" analyzing metadata for '" + oClassInfo.name + "'"); + // Read the stereotype information from the metadata + oClassInfo.stereotype = (metadata.stereotype && metadata.stereotype.value.value) || undefined; + oClassInfo["abstract"] = !!(metadata["abstract"] && metadata["abstract"].value.value); oClassInfo["final"] = !!(metadata["final"] && metadata["final"].value.value); oClassInfo.dnd = metadata.dnd && convertDragDropValue(metadata.dnd.value); @@ -1207,6 +1247,25 @@ function createAutoDoc(oClassInfo, classComment, node, parser, filename, comment return prefix + n.slice(0,1).toUpperCase() + n.slice(1); } + function generateParamTag(n, type, description, defaultValue){ + var s = "@param {" + info.type + "} "; + + if (defaultValue !== null) { + s += "[" + varname(n, type, true) + "="; + if (type === "string"){ + defaultValue = "\"" + defaultValue + "\""; + } + s += defaultValue + "]"; + + } else { + s += varname(n, type, true); + } + + s += " " + description; + + return s; + } + // add a list of the possible settings if and only if // - documentation for the constructor exists // - no (generated) documentation for settings exists already @@ -1353,7 +1412,7 @@ function createAutoDoc(oClassInfo, classComment, node, parser, filename, comment "", "@param {string} sClassName Name of the class being created", "@param {object} [oClassInfo] Object literal with information about the class", - "@param {function} [FNMetaImpl] Constructor function for the metadata object; if not given, it defaults to sap.ui.core.ElementMetadata", + "@param {function} [FNMetaImpl] Constructor function for the metadata object; if not given, it defaults to the metadata implementation used by this class", "@returns {function} Created class / constructor function", "@public", "@static", @@ -1391,7 +1450,7 @@ function createAutoDoc(oClassInfo, classComment, node, parser, filename, comment "When called with a value of null or undefined, the default value of the property will be restored.", "", info.defaultValue !== null ? "Default value is " + (info.defaultValue === "" ? "empty string" : info.defaultValue) + "." : "", - "@param {" + info.type + "} " + varname(n,info.type,true) + " New value for property " + n + "", + generateParamTag(n, info.type, "New value for property " + n + "", info.defaultValue), "@returns {" + oClassInfo.name + "} Reference to this in order to allow method chaining", info.since ? "@since " + info.since : "", info.deprecation ? "@deprecated " + info.deprecation : "", @@ -2064,7 +2123,6 @@ exports.defineTags = function(dictionary) { doclet.hideconstructor = true; } }); - }; exports.handlers = { @@ -2230,6 +2288,8 @@ exports.handlers = { // add metadata to symbol if ( classInfos[doclet.longname] ) { doclet.__ui5.metadata = classInfos[doclet.longname]; + // Push the stereotype to the main doclet.__ui5 object since that's where it's read. + doclet.__ui5.stereotype = classInfos[doclet.longname].stereotype; // add designtime infos, if configured var designtimeModule = doclet.__ui5.metadata.designtime; @@ -2273,6 +2333,28 @@ exports.handlers = { }; } + if ( doclet.kind === 'member' && doclet.isEnum && Array.isArray(doclet.properties) ) { + // determine unique enum identifier from key set + var enumID = doclet.properties.map(function(prop) { + return prop.name; + }).sort().join("|"); + if ( enumValues[enumID] ) { + // debug("found enum values for ", enumID, enumValues[enumID]); + var standardEnum = true; + /* eslint-disable no-loop-func */ + doclet.properties.forEach(function(prop) { + prop.__ui5.value = enumValues[enumID][prop.name]; + if ( prop.__ui5.value !== prop.name ) { + standardEnum = false; + } + }); + /* eslint-enable no-loop-func */ + if ( standardEnum ) { + doclet.__ui5.stereotype = 'enum'; + } + } + } + // check for duplicates: last one wins if ( j > 0 && doclets[j - 1].longname === doclet.longname ) { if ( !doclets[j - 1].synthetic && !doclet.__ui5.updatedDoclet ) { @@ -2326,6 +2408,18 @@ exports.astNodeVisitor = { } } + function processPotentialEnum(literal, comment) { + var values = literal.properties.reduce(function(map, prop) { + map[getPropertyKey(prop)] = convertValue(prop.value); + return map; + }, Object.create(null)); + // determine unique enum ID from key set + var enumID = Object.keys(values).sort().join("|"); + // and remember the values with that ID + enumValues[enumID] = values; + // debug("found enum values for key-set", enumID); + } + if ( node.type === Syntax.ExpressionStatement ) { if ( isSapUiDefineCall(node.expression) ) { analyzeModuleDefinition(node.expression); @@ -2367,6 +2461,9 @@ exports.astNodeVisitor = { comment = (idx === 0 ? getLeadingCommentNode(node) : undefined) || getLeadingCommentNode(decl); // console.log("ast node with comment " + comment); processExtendCall(decl.init, comment); + } else if ( isPotentialEnum(decl.init) ) { + comment = (idx === 0 ? getLeadingCommentNode(node) : undefined) || getLeadingCommentNode(decl); + processPotentialEnum(decl.init, comment); } }); @@ -2387,6 +2484,10 @@ exports.astNodeVisitor = { processDataType(node.expression.right); // TODO remember knowledge about type and its name (left hand side of assignment) + } else if ( isPotentialEnum(node.expression.right) ) { + comment = getLeadingCommentNode(node) || getLeadingCommentNode(node.expression); + // console.log(getResolvedObjectName(node.expression.left)); + processPotentialEnum(node.expression.right, comment); } } diff --git a/lib/processors/jsdoc/lib/ui5/template/publish.js b/lib/processors/jsdoc/lib/ui5/template/publish.js index 4ea98a10c..ac619c469 100644 --- a/lib/processors/jsdoc/lib/ui5/template/publish.js +++ b/lib/processors/jsdoc/lib/ui5/template/publish.js @@ -1,7 +1,7 @@ /* * JSDoc3 template for UI5 documentation generation. * - * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company. + * (c) Copyright 2009-2020 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ @@ -19,6 +19,7 @@ var template = require('jsdoc/template'), /* globals, constants */ var MY_TEMPLATE_NAME = "ui5", + MY_ALT_TEMPLATE_NAME = "sapui5-jsdoc3", ANONYMOUS_LONGNAME = doclet.ANONYMOUS_LONGNAME, A_SECURITY_TAGS = [ { @@ -56,8 +57,9 @@ var MY_TEMPLATE_NAME = "ui5", var rSecurityTags = new RegExp(A_SECURITY_TAGS.map(function($) {return $.name.toLowerCase(); }).join('|'), "i"); //debug(A_SECURITY_TAGS.map(function($) {return $.name; }).join('|')); -var templateConf = (env.conf.templates || {})[MY_TEMPLATE_NAME] || {}, - pluginConf = templateConf, +var templatesConf = (env.conf.templates || {}), + templateConf = templatesConf[MY_TEMPLATE_NAME] || templatesConf[MY_ALT_TEMPLATE_NAME] || {}, + pluginConf = templateConf, conf = {}, view; @@ -580,50 +582,51 @@ function publish(symbolSet) { var now = new Date(); info("start publishing"); - for (var i = 0; i < templateConf.variants.length; i++) { + if ( Array.isArray(templateConf.variants) ) { + templateConf.variants.forEach(function(vVariant) { - var vVariant = templateConf.variants[i]; - if ( typeof vVariant === "string" ) { - vVariant = { variant : vVariant }; - } - - info(""); - - if ( PUBLISHING_VARIANTS[vVariant.variant] ) { - - // Merge different sources of configuration (listed in increasing priority order - last one wins) - // and expose the result in the global 'conf' variable - // - global defaults - // - defaults for current variant - // - user configuration for sapui5 template - // - user configuration for current variant - // - // Note: trailing slash expected for dirs - conf = merge({ - ext: ".html", - filter: function($) { return true; }, - templatesDir: "/templates/sapui5/", - symbolsDir: "symbols/", - modulesDir: "modules/", - topicUrlPattern: "../../guide/{{topic}}.html", - srcDir: "symbols/src/", - creationDate : now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDay() + " " + now.getHours() + ":" + now.getMinutes(), - outdir: env.opts.destination - }, PUBLISHING_VARIANTS[vVariant.variant].defaults, templateConf, vVariant); - - info("publishing as variant '" + vVariant.variant + "'"); - debug("final configuration:"); - debug(conf); - - PUBLISHING_VARIANTS[vVariant.variant].processor(conf); + if ( typeof vVariant === "string" ) { + vVariant = { variant : vVariant }; + } - info("done with variant " + vVariant.variant); + info(""); + + if ( PUBLISHING_VARIANTS[vVariant.variant] ) { + + // Merge different sources of configuration (listed in increasing priority order - last one wins) + // and expose the result in the global 'conf' variable + // - global defaults + // - defaults for current variant + // - user configuration for sapui5 template + // - user configuration for current variant + // + // Note: trailing slash expected for dirs + conf = merge({ + ext: ".html", + filter: function($) { return true; }, + templatesDir: "/templates/sapui5/", + symbolsDir: "symbols/", + modulesDir: "modules/", + topicUrlPattern: "../../guide/{{topic}}.html", + srcDir: "symbols/src/", + creationDate : now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDay() + " " + now.getHours() + ":" + now.getMinutes(), + outdir: env.opts.destination + }, PUBLISHING_VARIANTS[vVariant.variant].defaults, templateConf, vVariant); + + info("publishing as variant '" + vVariant.variant + "'"); + debug("final configuration:"); + debug(conf); + + PUBLISHING_VARIANTS[vVariant.variant].processor(conf); + + info("done with variant " + vVariant.variant); - } else { + } else { - info("cannot publish unknown variant '" + vVariant.variant + "' (ignored)"); + info("cannot publish unknown variant '" + vVariant.variant + "' (ignored)"); - } + } + }); } var builtinSymbols = templateConf.builtinSymbols; @@ -741,17 +744,23 @@ function createInheritanceTree() { function getOrCreateClass(sClass, sExtendingClass) { var oClass = lookup(sClass); if ( !oClass ) { - warning("create missing class " + sClass + " (extended by " + sExtendingClass + ")"); - var sBaseClass = 'Object'; + var sKind = "class", + sBaseClass = 'Object', + sVisibility = "public"; if ( externalSymbols[sClass] ) { + sKind = externalSymbols[sClass].kind || sKind; sBaseClass = externalSymbols[sClass].extends || sBaseClass; + sVisibility = externalSymbols[sClass].visibility || sVisibility; + debug("create doclet for external class " + sClass + " (extended by " + sExtendingClass + ")"); + } else { + warning("create missing class " + sClass + " (extended by " + sExtendingClass + ")"); } var oBaseClass = getOrCreateClass(sBaseClass, sClass); oClass = makeDoclet(sClass, [ "@extends " + sBaseClass, - "@class", + "@" + sKind, "@synthetic", - "@public" + sVisibility === "restricted" ? "@ui5-restricted" : "@" + sVisibility ]); oClass.__ui5.base = oBaseClass; oBaseClass.__ui5.derived = oBaseClass.__ui5.derived || []; @@ -786,12 +795,17 @@ function createInheritanceTree() { for (var j = 0; j < oClass.implements.length; j++) { var oInterface = lookup(oClass.implements[j]); if ( !oInterface ) { - warning("create missing interface " + oClass.implements[j]); + var sVisibility = "public"; + if ( externalSymbols[oClass.implements[j]] ) { + sVisibility = externalSymbols[oClass.implements[j]] || sVisibility; + debug("create doclet for external interface " + oClass.implements[j]); + } else { + warning("create missing interface " + oClass.implements[j]); + } oInterface = makeDoclet(oClass.implements[j], [ - "@extends Object", "@interface", "@synthetic", - "@public" + sVisibility === "restricted" ? "@ui5-restricted" : "@" + sVisibility ]); oInterface.__ui5.base = oObject; oObject.__ui5.derived = oObject.__ui5.derived || []; @@ -1635,12 +1649,17 @@ function groupByContributors(symbol, aBorrowedMembers) { aSortedContributors = [], i,order; - aBorrowedMembers.forEach(function($) { - $ = lookup($.inherits); - if ($ && mContributors[$.memberof] == null) { - mContributors[$.memberof] = { order : MAX_ORDER, items : [$] }; + aBorrowedMembers.forEach(function(borrowed) { + var $ = lookup(borrowed.inherits); + if ($) { + if (mContributors[$.memberof] == null) { + mContributors[$.memberof] = { order : MAX_ORDER, items : [$] }; + } else { + mContributors[$.memberof].items.push($); + } } else { - mContributors[$.memberof].items.push($); + error("symbol '" + borrowed.longname + "' has 'inherited' flag set," + + " but inherits missing symbol '" + borrowed.inherits + "' (skipped)"); } }); @@ -1692,7 +1711,7 @@ function TypeParser(defaultBuilder) { * - function(this:) // type of this * - function(new:) // constructor */ - var rLexer = /\s*(Array\.?<|Object\.?<|Set\.?<|Promise\.?<|function\(|\{|:|\(|\||\}|>|\)|,|\[\]|\*|\?|!|\.\.\.)|\s*((?:module:)?\w+(?:[\/.#~]\w+)*)|./g; + var rLexer = /\s*(Array\.?<|Object\.?<|Set\.?<|Promise\.?<|function\(|\{|:|\(|\||\}|\.?<|>|\)|,|\[\]|\*|\?|!|\.\.\.)|\s*((?:module:)?\w+(?:[\/.#~]\w+)*)|./g; var input, builder, @@ -1831,9 +1850,24 @@ function TypeParser(defaultBuilder) { } else { type = builder.simpleType(tokenStr); next('symbol'); - while ( token === '[]' ) { + // check for suffix operators: either 'type application' (generics) or 'array', but not both of them + if ( token === "<" || token === ".<" ) { next(); - type = builder.array(type); + var templateTypes = []; + while ( token !== ">" ) { + var templateType = parseType(); + templateTypes.push(templateType); + if ( token === ',' ) { + next(); + } + } + next(">"); + type = builder.typeApplication(type, templateTypes); + } else { + while ( token === '[]' ) { + next(); + type = builder.array(type); + } } } if ( nullable ) { @@ -1937,6 +1971,13 @@ TypeParser.ASTBuilder = { repeatable: function(type) { type.repeatable = true; return type; + }, + typeApplication: function(type, templateTypes) { + return { + type: 'typeApplication', + baseType: type, + templateTypes: templateTypes + }; } }; @@ -1952,6 +1993,7 @@ TypeParser.LinkBuilder.prototype = { simpleType: function(type) { if ( this.linkStyle === 'text' ) { return { + simpleComponent: type !== "*", str: type }; } @@ -1964,9 +2006,10 @@ TypeParser.LinkBuilder.prototype = { }; }, array: function(componentType) { - if ( componentType.needsParenthesis ) { + if ( componentType.needsParenthesis || componentType.simpleComponent === false ) { return { - str: "Array.<" + componentType.str + ">" + simpleComponent: false, + str: "Array.<" + this.safe(componentType) + ">" }; } return { @@ -1976,25 +2019,30 @@ TypeParser.LinkBuilder.prototype = { object: function(keyType, valueType) { if ( keyType.synthetic ) { return { - str: "Object." + this.lt + valueType.str + this.gt + simpleComponent: false, + str: "Object." + this.lt + this.safe(valueType) + this.gt }; } return { - str: "Object." + this.lt + keyType.str + "," + valueType.str + this.gt + simpleComponent: false, + str: "Object." + this.lt + this.safe(keyType) + "," + this.safe(valueType) + this.gt }; }, set: function(elementType) { return { - str: 'Set.' + this.lt + elementType.str + this.gt + simpleComponent: false, + str: 'Set.' + this.lt + this.safe(elementType) + this.gt }; }, promise: function(fulfillmentType) { return { - str: 'Promise.' + this.lt + fulfillmentType.str + this.gt + simpleComponent: false, + str: 'Promise.' + this.lt + this.safe(fulfillmentType) + this.gt }; }, "function": function(paramTypes, returnType) { return { + simpleComponent: false, str: "function(" + paramTypes.map(function(type) { return type.str; }).join(',') + ")" + ( returnType ? " : " + this.safe(returnType) : "") }; }, @@ -2004,10 +2052,11 @@ TypeParser.LinkBuilder.prototype = { if ( structure[fieldName].synthetic ) { r.push(fieldName); } else { - r.push(fieldName + ":" + structure[fieldName].str); + r.push(fieldName + ":" + this.safe(structure[fieldName])); } } return { + simpleComponent: false, str: "{" + r.join(",") + "}" }; }, @@ -2032,6 +2081,12 @@ TypeParser.LinkBuilder.prototype = { repeatable: function(type) { type.str = "..." + type.str; return type; + }, + typeApplication: function(type, templateTypes) { + return { + simpleComponent: false, + str: this.safe(type) + this.lt + templateTypes.map(function(type) { return this.safe(type); }, this).join(',') + this.gt + }; } }; @@ -2175,11 +2230,18 @@ function createAPIJSON(symbols, filename) { // sort only a copy(!) of the symbols, otherwise the SymbolSet lookup is broken symbols.slice(0).sort(sortByAlias).forEach(function(symbol) { if ( isFirstClassSymbol(symbol) && !symbol.synthetic ) { // dump a symbol if it as a class symbol and if it is not a synthetic symbol - api.symbols.push(createAPIJSON4Symbol(symbol, false)); + try { + var json = createAPIJSON4Symbol(symbol, false); + api.symbols.push(json); + } catch (e) { + error("failed to create api summary for " + symbol.name, e); + throw e; + } } }); postProcessAPIJSON(api); + validateAPIJSON(api); fs.mkPath(path.dirname(filename)); fs.writeFileSync(filename, JSON.stringify(api), 'utf8'); @@ -2205,6 +2267,13 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { return true; } + // In some cases, JSDoc does not provide a basename in property symbol.name, but a partially qualified name + // this function reduces this to the base name + function basename(name) { + var p = name.lastIndexOf("."); + return p < 0 ? name : name.slice(p + 1); + } + function tag(name, value, omitEmpty) { if ( omitEmpty && !value ) { @@ -2632,7 +2701,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { if ( !suppressReturnValue ) { var returns = member.returns && member.returns.length && member.returns[0]; - var type = member.type || (returns && returns.type); + var type = (returns && returns.type) || member.type; type = listTypes(type); //if ( type && type !== 'void' ) { // attrib("type", type, 'void'); @@ -2679,7 +2748,12 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { } - function writeMethod(member, name) { + function writeMethod(member, name, canBeOptional) { + name = name || member.name; + var optional = /\?$/.test(name); + if ( optional ) { + name = name.slice(0,-1); + } tag("method"); attrib("name", name || member.name); if ( member.__ui5.module && member.__ui5.module !== symbol.__ui5.module ) { @@ -2696,6 +2770,9 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { if ( member.tags && member.tags.some(function(tag) { return tag.title === 'ui5-metamodel'; }) ) { attrib('ui5-metamodel', true, false, /* raw = */true); } + if ( canBeOptional && optional ) { + attrib("optional", true, false, /* raw = */true); + } methodSignature(member); @@ -2749,7 +2826,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { tag(kind); attrib("name", symbol.longname); - attrib("basename", symbol.name); + attrib("basename", basename(symbol.name)); if ( symbol.__ui5.resource ) { attrib("resource", symbol.__ui5.resource); } @@ -2793,16 +2870,20 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { var skipMembers = false; var i, j, member, param; + var standardEnum = false; if ( kind === 'class' ) { - if ( symbol.__ui5.stereotype || hasSettings(symbol) ) { + if ( symbol.__ui5.stereotype || (symbol.__ui5.metadata && symbol.__ui5.metadata.metadataClass) || hasSettings(symbol) ) { tag("ui5-metadata"); if ( symbol.__ui5.stereotype ) { attrib("stereotype", symbol.__ui5.stereotype); } + if ( symbol.__ui5.metadata && symbol.__ui5.metadata.metadataClass ) { + attrib("metadataClass", symbol.__ui5.metadata.metadataClass); + } writeMetadata(symbol); @@ -2810,7 +2891,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { } - // IF @hideconstructor tag is present we omit the whole constructor + // if @hideconstructor tag is present we omit the whole constructor if ( !symbol.hideconstructor ) { tag("constructor"); @@ -2851,7 +2932,9 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { } else if ( kind === 'typedef' ) { // typedefs have their own property structure skipMembers = true; - if ( symbol.properties && symbol.properties.length > 0 ) { + if ( symbol.params || symbol.returns || symbol.exceptions ) { + methodSignature(symbol); + } else if ( symbol.properties && symbol.properties.length > 0 ) { collection("properties"); symbol.properties.forEach(function(prop) { tag("property"); @@ -2863,6 +2946,13 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { }); endCollection("properties"); } + } else if ( kind === 'enum' ) { + if ( symbol.__ui5.stereotype ) { + tag("ui5-metadata"); + attrib("stereotype", symbol.__ui5.stereotype); + standardEnum = symbol.__ui5.stereotype === 'enum'; + closeTag("ui5-metadata"); + } } else if ( kind === 'function' ) { methodSignature(symbol); } @@ -2879,6 +2969,9 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { attrib("module", member.__ui5.module); attrib("export", undefined, '', true); } + if ( kind === 'enum' && !standardEnum && member.__ui5.value !== undefined ) { + attrib("value", member.__ui5.value, undefined, /* raw = */true); + } attrib("visibility", visibility(member), 'public'); if ( member.scope === 'static' ) { attrib("static", true, false, /* raw = */true); @@ -2956,10 +3049,11 @@ function createAPIJSON4Symbol(symbol, omitDefaults) { } var ownMethods = childrenOfKind(symbol, 'method').own.sort(sortByAlias); - if ( ownMethods.length > 0 ) { + // xmlmacro stereotype does not allow methods + if ( symbol.__ui5.stereotype !== 'xmlmacro' && ownMethods.length > 0 ) { collection("methods"); ownMethods.forEach(function(member) { - writeMethod(member); + writeMethod(member, undefined, symbol.kind === 'interface'); if ( member.__ui5.members ) { // HACK: export nested static functions as siblings of the current function // A correct representation has to be discussed with the SDK / WebIDE @@ -3049,7 +3143,10 @@ function postProcessAPIJSON(api) { symbols.forEach(function(symbol) { // debug("check ", symbol.name, "against", defaultExport, "and", moduleNamePath); - if ( symbol.name === moduleNamePath ) { + if ( symbol.symbol.kind === "typedef" || symbol.symbol.kind === "interface" ) { + // type definitions and interfaces have no representation on module level + symbol.symbol.export = undefined; + } else if ( symbol.name === moduleNamePath ) { // symbol name is the same as the module namepath -> symbol is the default export symbol.symbol.export = ""; } else if ( symbol.name.lastIndexOf(moduleNamePath + ".", 0) === 0 ) { @@ -3071,7 +3168,7 @@ function postProcessAPIJSON(api) { || (symbol.symbol.methods && symbol.symbol.methods.length > 0) ) { error("could not identify export name of '" + symbol.name + "', contained in module '" + moduleName + "'"); } else { - debug("could not identify export name of namespace '" + symbol.name + "', contained in module '" + moduleName + "'"); + debug("could not identify export name of " + symbol.symbol.kind + " '" + symbol.name + "', contained in module '" + moduleName + "'"); } } }); @@ -3081,6 +3178,398 @@ function postProcessAPIJSON(api) { for ( n in modules ) { guessExports(n, modules[n]); } + + function findSymbol(name) { + if ( name == null || name === '' ) { + return null; + } + return symbols.find(function(candidate) { + return candidate.name === name; + }) || externalSymbols[name]; + } + + function findMetadataClass(symbol) { + while ( symbol ) { + if ( symbol["ui5-metadata"] && symbol["ui5-metadata"].metadataClass ) { + var metadataSymbol = findSymbol(symbol["ui5-metadata"].metadataClass); + if ( metadataSymbol != null && metadataSymbol.visibility === "public" ) { + return symbol["ui5-metadata"].metadataClass; + } + } + symbol = findSymbol(symbol.extends); + } + // return undefined + } + + symbols.forEach(function(symbol) { + if ( !symbol["ui5-metadata"] ) { + return; + } + if ( Array.isArray(symbol.methods) ) { + symbol.methods.forEach(function(method) { + if ( method.name === "getMetadata" && method.returnValue ) { + var metadataClass = findMetadataClass(symbol); + if ( metadataClass && metadataClass !== method.returnValue.type ) { + method.returnValue.type = metadataClass; + debug(" return type of " + symbol.name + (method.static ? "." : "#") + "getMetadata changed to '" + metadataClass + "'"); + } + } + }); + } + }); + +} + +var builtinTypes = { + "void":true, + any:true, + "boolean":true, + "int": true, + "float":true, + array:true, + "function":true, + string:true, + object:true, + "*": true, + number:true, + "null":true, + undefined:true, + + // builtin objects + Array:true, + Boolean:true, + String:true, + Object:true, + Number:true, + Date:true, + RegExp:true, + Promise:true, + ArrayBuffer:true, + Uint8Array:true, + Error:true, + TypeError:true, + SyntaxError:true, + + // Web APIs + Blob:true, + Document:true, + Element:true, + Event:true, + File:true, + HTMLElement: true, + Node:true, + Touch:true, + TouchList:true, + Window: true + + }; + +var typeNormalizer = (function() { + function TypeNormalizer() { + TypeParser.LinkBuilder.call(this, 'text', false); + } + TypeNormalizer.prototype = Object.create(TypeParser.LinkBuilder.prototype); + TypeNormalizer.prototype.simpleType = function(type) { + if ( type === 'map' ) { + return this.object( + this.simpleType('string'), + this.simpleType('any') + ); + } + if ( type === '*' ) { + type = 'any'; + } + return TypeParser.LinkBuilder.prototype.simpleType.call(this, type); + }; + + return new TypeNormalizer(); +}()); + +function validateAPIJSON(api) { + + // create map of defined symbols (built-in types, dependency libraries, current library) + var defined = Object.assign(Object.create(null), builtinTypes, externalSymbols); + if ( api.symbols ) { + api.symbols.forEach(function(symbol) { defined[symbol.name] = symbol; }); + } + + var naming = Object.create(null); + var missing = Object.create(null); + + var rValidNames = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/i; + var rValidModuleNames = /^[$A-Z_a-z][$\-\.0-9A-Z_a-z]*$/i; + + function checkName(name, hint) { + if ( !rValidNames.test(name) ) { + naming[name] = naming[name] || []; + naming[name].push(hint); + } + } + + function checkModuleName(name, hint) { + if ( !rValidModuleNames.test(name) ) { + naming[name] = naming[name] || []; + naming[name].push(hint); + } + } + + function checkCompoundName(name, hint) { + + if ( name.startsWith("module:") ) { + var segments = name.slice("module:".length).split("/"); + + // split last segment into a module name part and a symbol name part + var p = segments[segments.length - 1].search(/[.~#]/); + if ( p >= 0 ) { + name = segments[segments.length - 1].slice(p + 1); + segments[segments.length - 1] = segments[segments.length - 1].slice(0, p); + } + + // check all module name parts + segments.forEach(function(segment) { + checkModuleName(segment, "path segment of " + hint); + }); + + if ( p < 0 ) { + // module name only, no export name to check + return; + } + } + + name.split(/[.~#]/).forEach(function(segment) { + checkName(segment, "name segment of " + hint); + }); + } + + function reportError(type, usage) { + missing[type] = missing[type] || []; + missing[type].push(usage); + } + + function checkSimpleType(typeName, hint) { + if ( !defined[typeName] ) { + reportError(typeName, hint); + } + } + + function checkType(type, hint) { + + function _check(type) { + if ( type == null ) { + return; + } + switch (type.type) { + case 'simpleType': + checkSimpleType(type.name, hint); + break; + case 'array': + _check(type.component); + break; + case 'object': + _check(type.key); + _check(type.value); + break; + case 'set': + _check(type.element); + break; + case 'promise': + _check(type.fulfill); + break; + case 'function': + type.params.forEach(_check); + _check(type.return); + _check(type.this); + _check(type.constructor); + break; + case 'structure': + Object.keys(type.fields).forEach(function(key) { + _check(type.fields[key]); + }); + break; + case 'union': + type.types.forEach(_check); + break; + case 'typeApplication': + _check(type.baseType); + type.templateTypes.forEach(_check); + // TODO check number of templateTypes against declaration of baseType + // requires JSDoc support of @template tag, which is currently missing + break; + default: + break; + } + } + try { + // debug("normalize", type); + type.type = typeParser.parse(type.type, typeNormalizer).str; + // debug("check", type); + var ast = typeParser.parse(type.type); + _check(ast); + } catch (e) { + error(e); + reportError(type.type, "failed to parse type of " + hint); + } + } + + function checkParam(param, prefix, hint) { + checkName(param.name, "name of param " + prefix + param.name + " of " + hint); + checkType(param, "param " + prefix + param.name + " of " + hint); + if ( param.parameterProperties ) { + Object.keys(param.parameterProperties).forEach(function(sub) { + checkParam(param.parameterProperties[sub], prefix + param.name + ".", hint); + }); + } + } + + function checkMethodSignature(method, hint) { + if ( method.returnValue ) { + checkType(method.returnValue, "return value of " + hint); + } + if ( method.parameters ) { + method.parameters.forEach(function(param) { + checkParam(param, '', hint); + }); + } + if ( method.throws ) { + method.throws.forEach(function(ex) { + checkType(ex, "exception of " + hint); + }); + } + } + + function checkClassAgainstInterface(symbol, oIntfAPI) { + if ( oIntfAPI.methods ) { + oIntfAPI.methods.forEach(function(intfMethod) { + // search for method implementation + var implMethod = symbol.methods.find(function(candidateMethod) { + return candidateMethod.name === intfMethod.name && !candidateMethod.static; + }); + if ( !implMethod ) { + if ( !intfMethod.optional ) { + reportError(oIntfAPI.name, "implementation of " + intfMethod.name + " missing in " + symbol.name); + } + } else { + if ( intfMethod.parameters ) { + intfMethod.parameters.forEach(function(intfParam, idx) { + var implParam = implMethod.parameters && implMethod.parameters[idx]; + if ( !implParam ) { + if ( !intfParam.optional ) { + reportError(oIntfAPI.name, "parameter " + intfParam.name + " missing in implementation of " + symbol.name + "#" + intfMethod.name); + } + } else { + if ( implParam.type !== intfParam.type ) { + reportError(oIntfAPI.name, "type of parameter " + intfParam.name + " of interface method differs from type in implementation " + symbol.name + "#" + intfMethod.name); + } + // TODO check nested properties + } + }); + } + if ( intfMethod.returnValue != null && implMethod.returnValue == null ) { + reportError(oIntfAPI.name, "return value of interface method missing in implementation " + symbol.name + "#" + intfMethod); + } else if ( intfMethod.returnValue == null && implMethod.returnValue != null ) { + reportError(oIntfAPI.name, "while interface method is void, implementation " + symbol.name + "#" + intfMethod.name + " returns a value"); + } else if ( intfMethod.returnValue != null && implMethod.returnValue != null ) { + if ( intfMethod.returnValue.type !== implMethod.returnValue.type ) { + reportError(oIntfAPI.name, "return type of interface method differs from return type of implementation " + symbol.name + "#" + intfMethod.name); + } + } + } + }); + } + } + + function checkEnum(symbol) { + if ( symbol["ui5-metamodel"] && !(symbol["ui5-metadata"] && symbol["ui5-metadata"].stereotype === "enum") ) { + reportError(symbol.name, "enum is metamodel relevant but keys and values differ"); + } + checkCompoundName(symbol.name, "name of " + symbol.name); + if ( symbol.properties ) { + symbol.properties.forEach(function(prop) { + checkName(prop.name, "name of " + symbol.name + "." + prop.name); + if ( prop.type ) { + checkType(prop, "type of " + symbol.name + "." + prop.name); + } + }); + } + } + + function checkClass(symbol) { + checkCompoundName(symbol.name, "name of " + symbol.name); + if ( symbol.extends ) { + checkSimpleType(symbol.extends, "base class of " + symbol.name); + } + if ( symbol.implements ) { + symbol.implements.forEach(function(intf) { + checkSimpleType(intf, "interface of " + symbol.name); + var oIntfAPI = defined[intf]; + if ( oIntfAPI ) { + checkClassAgainstInterface(symbol, oIntfAPI); + } + }); + } + if ( Object.prototype.hasOwnProperty.call(symbol, "constructor") ) { + checkMethodSignature(symbol.constructor, symbol.name + ".constructor"); + } + if ( symbol.properties ) { + symbol.properties.forEach(function(prop) { + checkName(prop.name, "name of " + symbol.name + "." + prop.name); + if ( prop.type ) { + checkType(prop, "type of " + symbol.name + "." + prop.name); + } + }); + } + if ( symbol.methods ) { + symbol.methods.forEach(function(method) { + checkName(method.name, "name of " + symbol.name + "." + method.name); + checkMethodSignature(method, symbol.name + "." + method.name); + }); + } + if ( symbol.events ) { + symbol.events.forEach(function(event) { + checkName(event.name, "name of " + symbol.name + "." + event.name); + if ( event.parameters ) { + event.parameters.forEach(function(param) { + checkParam(param, '', symbol.name + "." + event.name); + }); + } + }); + } + } + + api.symbols.forEach(function(symbol) { + if ( symbol.kind === 'function' ) { + checkCompoundName(symbol.name, "name of " + symbol.name); + checkMethodSignature(symbol, symbol.name); + } else if ( symbol.kind === 'enum' ) { + checkEnum(symbol); + } else { + checkClass(symbol); + } + }); + + if ( Object.keys(missing).length > 0 || Object.keys(naming).length > 0 ) { + error("API validation errors:"); + + Object.keys(missing).forEach(function(type) { + if ( Array.isArray(missing[type]) ) { + error("type '" + type + "'"); + missing[type].forEach(function(usage) { + error(" " + usage); + }); + } + }); + Object.keys(naming).forEach(function(name) { + if ( Array.isArray(naming[name]) ) { + error("invalid name '" + name + "'"); + naming[name].forEach(function(usage) { + error(" " + usage); + }); + } + }); + } else { + info("API validation succeeded."); + } + } //---- add on: API XML ----------------------------------------------------------------- diff --git a/lib/processors/jsdoc/sdkTransformer.js b/lib/processors/jsdoc/sdkTransformer.js index 0dbb98dd2..351ebd5d3 100644 --- a/lib/processors/jsdoc/sdkTransformer.js +++ b/lib/processors/jsdoc/sdkTransformer.js @@ -1,5 +1,5 @@ const resourceFactory = require("@ui5/fs").resourceFactory; -const transformer = require("./lib/transform-apijson-for-sdk"); +const transformer = require("./lib/transformApiJson"); /** * Transform api.json as created by [jsdocGenerator]{@link module:@ui5/builder.processors.jsdocGenerator} @@ -7,7 +7,7 @@ const transformer = require("./lib/transform-apijson-for-sdk"); * * @public * @alias module:@ui5/builder.processors.sdkTransformer - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {string} parameters.apiJsonPath Path to the projects api.json file as created by * [jsdocGenerator]{@link module:@ui5/builder.processors.jsdoc.jsdocGenerator} * @param {string} parameters.dotLibraryPath Path to the projects .library file diff --git a/lib/processors/manifestCreator.js b/lib/processors/manifestCreator.js index 4551af927..ed9395095 100644 --- a/lib/processors/manifestCreator.js +++ b/lib/processors/manifestCreator.js @@ -1,5 +1,6 @@ "use strict"; +const posixPath = require("path").posix; const {SemVer: Version} = require("semver"); const log = require("@ui5/logger").getLogger("builder:processors:manifestCreator"); const EvoResource = require("@ui5/fs").Resource; @@ -36,10 +37,10 @@ function getBooleanAttribute(node, attr) { } function findChild(node, tagName, namespaceURI) { - if ( node - && Array.isArray(node[tagName]) - && node[tagName].length > 0 - && (namespaceURI == null || (node[tagName][0].$ns && node[tagName][0].$ns.uri === namespaceURI)) ) { + if ( node && + Array.isArray(node[tagName]) && + node[tagName].length > 0 && + (namespaceURI == null || (node[tagName][0].$ns && node[tagName][0].$ns.uri === namespaceURI)) ) { return node[tagName][0]; } } @@ -155,21 +156,80 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in // return undefined } - function createSapApp() { - function findComponentPaths() { + async function createSapApp() { + async function isEmbeddedByLibrary(componentPath, libraryPathPrefix) { + const manifestPath = componentPath + "/manifest.json"; + + const manifestResource = libBundle.findResource(manifestPath.substring(libraryPathPrefix.length)); + if ( manifestResource == null ) { + log.verbose(" component has no accompanying manifest.json, don't list it as 'embedded'"); + return false; + } + const manifestString = await manifestResource.getString(); + let manifest; + try { + manifest = JSON.parse(manifestString); + } catch (err) { + log.error( + " component '%s': failed to read the component's manifest.json, " + + "it won't be listed as 'embedded'.\nError details: %s", componentPath, err.stack); + return false; + } + let embeddedBy; + if (manifest && manifest["sap.app"]) { + embeddedBy = manifest["sap.app"]["embeddedBy"]; + } + if (typeof embeddedBy === "undefined") { + log.verbose(" component doesn't declare 'sap.app/embeddedBy', don't list it as 'embedded'"); + return false; + } + if (typeof embeddedBy !== "string") { + log.error( + " component '%s': property 'sap.app/embeddedBy' is of type '%s' (expected 'string'), " + + "it won't be listed as 'embedded'", componentPath, typeof embeddedBy + ); + return false; + } + if ( !embeddedBy.length ) { + log.error( + " component '%s': property 'sap.app/embeddedBy' has an empty string value (which is invalid), " + + "it won't be listed as 'embedded'", componentPath + ); + return false; + } + let resolvedEmbeddedBy = posixPath.resolve(componentPath, embeddedBy); + if ( resolvedEmbeddedBy && !resolvedEmbeddedBy.endsWith("/") ) { + resolvedEmbeddedBy = resolvedEmbeddedBy + "/"; + } + if ( libraryPathPrefix === resolvedEmbeddedBy ) { + log.verbose(" component's 'sap.app/embeddedBy' property points to library, list it as 'embedded'"); + return true; + } else { + log.verbose( + " component's 'sap.app/embeddedBy' points to '%s', don't list it as 'embedded'", resolvedEmbeddedBy + ); + return false; + } + } + + async function findEmbeddedComponents() { const result = []; const prefix = libraryResource.getPath().slice(0, - ".library".length); const components = libBundle.getResources(/^\/(?:[^/]+\/)*Component\.js$/); - components.forEach((comp) => { - const relativePath = comp.getPath().slice(prefix.length); - if ( relativePath.lastIndexOf("/") >= 0 ) { - result.push( relativePath.slice(0, relativePath.lastIndexOf("/")) ); - } else if ( prefix !== "/resources/sap/ui/core/" ) { + for (const comp of components) { + const componentPath = comp.getPath().slice(0, - "Component.js".length - 1); + log.verbose("checking component at %s", componentPath); + if ( componentPath.startsWith(prefix) && await isEmbeddedByLibrary(componentPath, prefix) ) { + result.push( componentPath.substring(prefix.length) ); + } else if ( prefix === "/resources/sap/apf/" ) { + log.verbose("Package %s contains both '*.library' and 'Component.js'. " + + "This is a known issue but can't be solved due to backward compatibility.", componentPath); + } else if ( prefix === (componentPath + "/") && prefix !== "/resources/sap/ui/core/" ) { log.error("Package %s contains both '*.library' and 'Component.js'. " + "This is not supported by manifests, therefore the component won't be " + - "listed in the library's manifest.", comp.getPath()); + "listed in the library's manifest.", componentPath); } - }); + } return result.sort(); } @@ -267,7 +327,7 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in _version: sectionVersion(APP_DESCRIPTOR_V3_SECTION_SAP_APP), id: library.getName(), type: "library", - embeds: findComponentPaths(), + embeds: await findEmbeddedComponents(), i18n: getChildTextContent(manifestAppData, "i18n"), applicationVersion: { version: isValid(library.getVersion()) ? library.getVersion() : getProjectVersion() @@ -541,7 +601,7 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in return { "_version": descriptorVersion.toString(), - "sap.app": createSapApp(), + "sap.app": await createSapApp(), "sap.ui": createSapUi(), "sap.ui5": createSapUI5(), "sap.fiori": createSapFiori(), @@ -568,10 +628,11 @@ module.exports = function({libraryResource, resources, options}) { return Promise.resolve(null); // a fulfillment of null indicates that no manifest has been created } - return createManifest(libraryResource, libBundle, options.descriptorVersion, options.include3rdParty).then((manifest) => { - return new EvoResource({ - path: resourcePathPrefix + "manifest.json", - string: JSON.stringify(manifest, null, options.prettyPrint ? " " : undefined) + return createManifest(libraryResource, libBundle, options.descriptorVersion, options.include3rdParty) + .then((manifest) => { + return new EvoResource({ + path: resourcePathPrefix + "manifest.json", + string: JSON.stringify(manifest, null, options.prettyPrint ? " " : undefined) + }); }); - }); }; diff --git a/lib/processors/nonAsciiEscaper.js b/lib/processors/nonAsciiEscaper.js index 66b025d1d..c45bf3d25 100644 --- a/lib/processors/nonAsciiEscaper.js +++ b/lib/processors/nonAsciiEscaper.js @@ -59,15 +59,16 @@ const escapeNonAscii = function(string) { * * @public * @alias module:@ui5/builder.processors.nonAsciiEscaper - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed - * @param {Object} [parameters.options] Options - * @param {string} [parameters.options.encoding="utf8"] resource file encoding (node.js based encodings). Use #getEncodingFromAlias to get the encoding string - * {@link https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings Node.js character encodings}; + * @param {object} [parameters.options] Options + * @param {string} [parameters.options.encoding="utf8"] resource file encoding + * ({@link https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings Node.js character encodings}). + * Use #getEncodingFromAlias to get the encoding string * @returns {Promise} Promise resolving with the processed resources */ -module.exports = async function nonAsciiEscaper({resources, options={}}) { - const encoding = options.encoding || "utf8"; +async function nonAsciiEscaper({resources, options: {encoding}}) { + encoding = encoding || "utf8"; async function processResource(resource) { const resourceString = (await resource.getBuffer()).toString(encoding); @@ -80,7 +81,7 @@ module.exports = async function nonAsciiEscaper({resources, options={}}) { } return Promise.all(resources.map(processResource)); -}; +} const encodingMap = { "UTF-8": "utf8", @@ -89,15 +90,20 @@ const encodingMap = { /** * Provides a mapping from user-friendly encoding name (alias) such as "UTF-8" and "ISO-8859-1" to node - * specific encoding name such as "utf8" or "latin1". Simplifies usage of nonAsciiEscaper encoding - * option such that it can be used standalone without the respective task (e.g. in Splitter, Bundler and related projects). + * specific encoding name such as "utf8" or "latin1". Simplifies usage of nonAsciiEscaper encoding option + * such that it can be used standalone without the respective task (e.g. in Splitter, Bundler and related projects). * + * @public + * @alias module:@ui5/builder.processors.nonAsciiEscaper․getEncodingFromAlias * @param {string} encoding encoding labels: "UTF-8" and "ISO-8859-1" * @returns {string} node.js character encoding string, e.g. utf8 and latin1 */ -module.exports.getEncodingFromAlias = function(encoding) { +nonAsciiEscaper.getEncodingFromAlias = function(encoding) { if (!encodingMap[encoding]) { - throw new Error(`Encoding "${encoding}" is not supported. Only ${Object.keys(encodingMap).join(", ")} are allowed values` ); + throw new Error( + `Encoding "${encoding}" is not supported. Only ${Object.keys(encodingMap).join(", ")} are allowed values` ); } return encodingMap[encoding]; }; + +module.exports = nonAsciiEscaper; diff --git a/lib/processors/resourceCopier.js b/lib/processors/resourceCopier.js index baee5be96..dd6247854 100644 --- a/lib/processors/resourceCopier.js +++ b/lib/processors/resourceCopier.js @@ -3,21 +3,21 @@ * * @public * @alias module:@ui5/builder.processors.resourceCopier - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed - * @param {Object} [parameters.options] Options - * @param {string} [parameters.options.pattern] Search pattern for path - * @param {string} [parameters.options.replacement] Replacement string for path + * @param {object} parameters.options Options + * @param {string} parameters.options.pattern Search pattern for path + * @param {string} parameters.options.replacement Replacement string for path * @returns {Promise} Promise resolving with the cloned resources */ -module.exports = function({resources, options}) { - if (!options.pattern || typeof options.replacement !== "string") { +module.exports = function({resources, options: {pattern, replacement}}) { + if (!pattern || typeof replacement !== "string") { return Promise.reject(new Error("[resourceCopier] Invalid options: Missing pattern or replacement.")); } return Promise.all(resources.map((resource) => { return resource.clone().then((newResource) => { - newResource.setPath(newResource.getPath().replace(options.pattern, options.replacement)); + newResource.setPath(newResource.getPath().replace(pattern, replacement)); return newResource; }); })); diff --git a/lib/processors/resourceListCreator.js b/lib/processors/resourceListCreator.js new file mode 100644 index 000000000..11645fc17 --- /dev/null +++ b/lib/processors/resourceListCreator.js @@ -0,0 +1,202 @@ +"use strict"; + +const log = require("@ui5/logger").getLogger("builder:processors:resourceListCreator"); +const ResourceCollector = require("../lbt/resources/ResourceCollector"); +const LocatorResourcePool = require("../lbt/resources/LocatorResourcePool"); +const ResourceInfo = require("../lbt/resources/ResourceInfo"); + +const EvoResource = require("@ui5/fs").Resource; + +/** + * List of resource patterns that describe all debug resources. + * + * @since 1.29.1 + */ +const DEFAULT_DEBUG_RESOURCES_FILTER = [ + "**/*-dbg.js", + "**/*-dbg.controller.js", + "**/*-dbg.designtime.js", + "**/*-dbg.support.js", + "**/*-dbg.view.js", + "**/*-dbg.fragment.js", + "**/*-dbg.css", + "**/*.js.map" +]; + +/** + * List of resource patterns that describe bundled resources. + * + * @since 1.29.1 + */ +const DEFAULT_BUNDLE_RESOURCES_FILTER = [ + "**/Component-preload.js", + "**/library-preload.js", + "**/library-preload-dbg.js", + "**/library-preload.json", + "**/library-h2-preload.js", + "**/designtime/library-preload.designtime.js", + "**/library-preload.support.js", + "**/library-all.js", + "**/library-all-dbg.js" +]; + +/** + * List of resource patterns that describe all designtime resources. + * + * @since 1.31.0 + */ +const DEFAULT_DESIGNTIME_RESOURCES_FILTER = [ + "**/designtime/*", + "**/*.designtime.js", + "**/*.control", + "**/*.interface", + "**/*.type", + "**/themes/*/*.less", + "**/library.templates.xml", + "**/library.dependencies.xml", + "**/library.dependencies.json" +]; + +/** + * List of resource patterns that describe all support (assistant) resources. + * + * @since 1.53.0 + */ +const DEFAULT_SUPPORT_RESOURCES_FILTER = [ + "**/*.support.js" +]; + +/** + * Hard coded debug bundle, to trigger separate analysis for this filename + * because sap-ui-core.js and sap-ui-core-dbg.js have different includes + * + * @type {string[]} + */ +const DEBUG_BUNDLES = [ + "sap-ui-core-dbg.js", + "sap-ui-core-nojQuery-dbg.js" +]; + +/** + * Creates and adds resources.json entry (itself) to the list. + * + * Retrieves the string content of the overall result and returns it. + * + * @param {ResourceInfoList} list resources list + * @param {string} prefix + * @returns {string} new content with resources.json entry + */ +function makeResourcesJSON(list, prefix) { + // having the file size entry part of the file is a bit like the chicken egg scenario + // you can't change the value of the file size without changing the file size + // so this part here tries to cope with that. + + // try to add resources.json entry with previous size of the list string. + // get the content to be added (resources.json entry) + // modify the size of the entry from the calculated one + + let contentString = JSON.stringify(list, null, "\t"); + const resourcesJson = new ResourceInfo(prefix + "resources.json"); + // initial size + resourcesJson.size = Buffer.from(contentString).byteLength; + list.add(resourcesJson); + + contentString = JSON.stringify(list, null, "\t"); + + let newLength = Buffer.from(contentString).byteLength; + + // Adjust size until it is correct + // This entry's size depends on the file size which depends on this entry's size,... + // Updating the number of the size in the content might influence the size of the file itself + // This is deterministic because e.g. in the content -> "size": 1000 has the same + // amount of bytes as "size": 9999 the difference might only come for: + // * adding the initial entry of resources.json + // * changes when the number of digits of the number changes, e.g. 100 -> 1000 + while (resourcesJson.size !== newLength) { + resourcesJson.size = newLength; + list.add(resourcesJson); + contentString = JSON.stringify(list, null, "\t"); + newLength = Buffer.from(contentString).byteLength; + } + return contentString; +} + +/** + * Creates resources.json files + * + * @private + * @param {object} parameters Parameters + * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources + * @param {object} [parameters.options] Options + * @returns {Promise} Promise resolving with the resources.json resources + */ +module.exports = async function({resources, options}) { + options = Object.assign({ + failOnOrphans: false, + externalResources: undefined, + debugResources: DEFAULT_DEBUG_RESOURCES_FILTER, + mergedResources: DEFAULT_BUNDLE_RESOURCES_FILTER, + designtimeResources: DEFAULT_DESIGNTIME_RESOURCES_FILTER, + supportResources: DEFAULT_SUPPORT_RESOURCES_FILTER, + debugBundles: DEBUG_BUNDLES + }, options); + + const pool = new LocatorResourcePool(); + await pool.prepare( resources ); + + const collector = new ResourceCollector(pool); + const visitPromises = resources.map((resource) => collector.visitResource(resource)); + + await Promise.all(visitPromises); + log.verbose(` found ${collector.resources.size} resources`); + + // determine additional information for the found resources + if ( options && options.externalResources ) { + collector.setExternalResources(options.externalResources); + } + + await collector.determineResourceDetails({ + pool, + debugResources: options.debugResources, + mergedResources: options.mergedResources, + designtimeResources: options.designtimeResources, + supportResources: options.supportResources, + debugBundles: options.debugBundles + }); + + // group resources by components and create ResourceInfoLists + collector.groupResourcesByComponents(); + + const resourceLists = []; + + // write out resources.json files + for (const [prefix, list] of collector.components.entries()) { + log.verbose(` writing '${prefix}resources.json'`); + + const contentString = makeResourcesJSON(list, prefix); + + resourceLists.push(new EvoResource({ + path: `/resources/${prefix}resources.json`, + string: contentString + })); + } + for (const [prefix, list] of collector.themePackages.entries()) { + log.verbose(` writing '${prefix}resources.json'`); + + const contentString = makeResourcesJSON(list, prefix); + + resourceLists.push(new EvoResource({ + path: `/resources/${prefix}resources.json`, + string: contentString + })); + } + const unassigned = collector.resources; + if ( unassigned.size > 0 && options.failOnOrphans ) { + log.error(`resources.json generation failed because of unassigned resources: ${[...unassigned].join(", ")}`); + throw new Error( + `resources.json generation failed with error: There are ${unassigned.size} ` + + `resources which could not be assigned to components.`); + } + + return resourceLists; +}; diff --git a/lib/processors/stringReplacer.js b/lib/processors/stringReplacer.js index a18916636..e2bf0fcee 100644 --- a/lib/processors/stringReplacer.js +++ b/lib/processors/stringReplacer.js @@ -5,17 +5,18 @@ const replaceStream = require("replacestream"); * * @public * @alias module:@ui5/builder.processors.stringReplacer - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.pattern Pattern of placeholders * @param {string} parameters.options.replacement Replacement for placeholders * @returns {Promise} Promise resolving with modified resources */ -module.exports = function({resources, options}) { +module.exports = function({resources, options: {pattern, replacement}}) { return Promise.all(resources.map((resource) => { - const stream = resource.getStream() - .pipe(replaceStream(options.pattern, options.replacement)); + let stream = resource.getStream(); + stream.setEncoding("utf8"); + stream = stream.pipe(replaceStream(pattern, replacement)); resource.setStream(stream); return resource; diff --git a/lib/processors/themeBuilder.js b/lib/processors/themeBuilder.js index 5df68ab40..e1e9f74e3 100644 --- a/lib/processors/themeBuilder.js +++ b/lib/processors/themeBuilder.js @@ -28,11 +28,14 @@ class ThemeBuilder { * * @public * @param {module:@ui5/fs.Resource[]} resources Library files - * @param {Object} [options] Build options + * @param {object} [options] Build options * @param {boolean} [options.compress=false] Compress build output (CSS / JSON) + * @param {boolean} [options.cssVariables=false] Generates the CSS variables + * (css-variables.css, css-variables.source.less) and the skeleton for a theme + * (library-skeleton.css, [library-skeleton-RTL.css]) * @returns {Promise} Resolving with array of created files */ - build(resources, {compress = false} = {}) { + build(resources, {compress = false, cssVariables = false} = {}) { const files = []; const compile = (resource) => { @@ -51,7 +54,8 @@ class ThemeBuilder { }, compiler: { compress - } + }, + cssVariables }).then((result) => { const themeDir = path.dirname(resource.getPath()); @@ -71,6 +75,30 @@ class ThemeBuilder { }); files.push(libCss, libCssRtl, libParams); + + if (cssVariables) { + const libCssVarsSource = new Resource({ + path: themeDir + "/css_variables.source.less", + string: result.cssVariablesSource + }); + const libCssVars = new Resource({ + path: themeDir + "/css_variables.css", + string: result.cssVariables + }); + const libCssSkel = new Resource({ + path: themeDir + "/library_skeleton.css", + string: result.cssSkeleton + }); + const libCssSkelRtl = new Resource({ + path: themeDir + "/library_skeleton-RTL.css", + string: result.cssSkeletonRtl + }); + + files.push(libCssVarsSource, libCssVars, libCssSkel, libCssSkelRtl); + } + }, (err) => { + log.error(`Error while compiling ${resource.getPath()}: ${err.message}`); + throw err; }); }; @@ -90,22 +118,40 @@ class ThemeBuilder { } } +/** + * + * @public + * @typedef {object} ThemeBuilderOptions + * @property {boolean} [compress=false] Compress build output (CSS / JSON) + * @property {boolean} [cssVariables=false] Generates the CSS variables + * (css-variables.css, css-variables.source.less) and the skeleton for a theme + * (library-skeleton.css, [library-skeleton-RTL.css]) + */ + /** * Builds a library theme. * * @public * @alias module:@ui5/builder.processors.themeBuilder - * @param {Object} parameters Parameters - * @param {module:@ui5/fs.Resource[]} parameters.resources List of library.source.less resources to be processed - * @param {fs|module:@ui5/fs.fsInterface} parameters.fs Node fs or custom [fs interface]{@link module:resources/module:@ui5/fs.fsInterface} - * @param {Object} [parameters.options] Options - * @param {Object} [parameters.options.compress=false] Compress build output (CSS / JSON) + * @param {object} parameters Parameters + * @param {module:@ui5/fs.Resource[]} parameters.resources List of library.source.less + * resources to be processed + * @param {fs|module:@ui5/fs.fsInterface} parameters.fs Node fs or custom + * [fs interface]{@link module:resources/module:@ui5/fs.fsInterface} + * @param {ThemeBuilderOptions} [parameters.options] Options * @returns {Promise} Promise resolving with theme resources */ -module.exports = ({resources, fs, options}) => { +module.exports = async function({ + resources, + fs, + options = {} +}) { + const {compress, cssVariables} = /** @type {ThemeBuilderOptions} */ (options); const themeBuilder = new ThemeBuilder({fs}); - const compress = options && options.compress; - return themeBuilder.build(resources, {compress}).then((files) => { + return themeBuilder.build(resources, { + compress, + cssVariables + }).then((files) => { themeBuilder.clearCache(); return files; }); diff --git a/lib/processors/uglifier.js b/lib/processors/uglifier.js index 4ff321e1a..7b6e1ebc9 100644 --- a/lib/processors/uglifier.js +++ b/lib/processors/uglifier.js @@ -1,36 +1,45 @@ const terser = require("terser"); -const copyrightCommentsPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9/i; +/** + * Preserve comments which contain: + *
    + *
  • copyright notice
  • + *
  • license terms
  • + *
  • "@ui5-bundle"
  • + *
  • "@ui5-bundle-raw-include"
  • + *
+ * + * @type {RegExp} + */ +const copyrightCommentsAndBundleCommentPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9|^@ui5-bundle-raw-include |^@ui5-bundle /i; /** * Minifies the supplied resources. * * @public * @alias module:@ui5/builder.processors.uglifier - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed * @returns {Promise} Promise resolving with uglified resources */ module.exports = function({resources}) { - return Promise.all(resources.map((resource) => { - return resource.getString().then((code) => { - const result = terser.minify({ + return Promise.all(resources.map(async (resource) => { + const code = await resource.getString(); + try { + const result = await terser.minify({ [resource.getPath()]: code }, { - warnings: false, output: { - comments: copyrightCommentsPattern, + comments: copyrightCommentsAndBundleCommentPattern, wrap_func_args: false }, compress: false }); - if (result.error) { - throw new Error( - `Uglification failed with error: ${result.error.message} in file ${result.error.filename} ` + - `(line ${result.error.line}, col ${result.error.col}, pos ${result.error.pos})`); - } - resource.setString(result.code); return resource; - }); + } catch (err) { + throw new Error( + `Uglification failed with error: ${err.message} in file ${err.filename} ` + + `(line ${err.line}, col ${err.col}, pos ${err.pos})`); + } })); }; diff --git a/lib/processors/versionInfoGenerator.js b/lib/processors/versionInfoGenerator.js index 61b4ab31f..39189b5d8 100644 --- a/lib/processors/versionInfoGenerator.js +++ b/lib/processors/versionInfoGenerator.js @@ -19,11 +19,12 @@ function getTimestamp() { * * @public * @alias module:@ui5/builder.processors.versionInfoGenerator - * @param {Object} parameters Parameters - * @param {Object} parameters.options Options + * @param {object} parameters Parameters + * @param {object} parameters.options Options * @param {string} parameters.options.rootProjectName Name of the root project * @param {string} parameters.options.rootProjectVersion Version of the root project - * @param {Array} parameters.options.libraryInfos Array of objects representing libraries, e.g. {name: "library.xy", version: "1.0.0"} + * @param {Array} parameters.options.libraryInfos Array of objects representing libraries, + * e.g. {name: "library.xy", version: "1.0.0"} * @returns {Promise} Promise resolving with an array containing the versioninfo resource */ diff --git a/lib/tasks/TaskUtil.js b/lib/tasks/TaskUtil.js new file mode 100644 index 000000000..54cb67ea9 --- /dev/null +++ b/lib/tasks/TaskUtil.js @@ -0,0 +1,154 @@ +/** + * Convenience functions for UI5 Builder tasks. + * An instance of this class is passed to every standard UI5 Builder task that requires it. + * + * Custom tasks that define a specification version >= 2.2 will receive an interface + * to an instance of this class when called. + * The set of available functions on that interface depends on the specification + * version defined for the extension. + * + * @public + * @memberof module:@ui5/builder.tasks + */ +class TaskUtil { + /** + * Standard Build Tags. See UI5 Tooling + * [RFC 0008]{@link https://github.com/SAP/ui5-tooling/blob/master/rfcs/0008-resource-tagging-during-build.md} + * for details. + * + * @public + * @typedef {object} module:@ui5/builder.tasks.TaskUtil~StandardBuildTags + * @property {string} OmitFromBuildResult + * Setting this tag to true for a resource will prevent it from being written to the build target + */ + + /** + * Since @ui5/builder.builder.ProjectBuildContext is a private class, TaskUtil must not be + * instantiated by modules other than @ui5/builder itself. + * + * @param {object} parameters + * @param {module:@ui5/builder.builder.ProjectBuildContext} parameters.projectBuildContext ProjectBuildContext + * @public + */ + constructor({projectBuildContext}) { + this._projectBuildContext = projectBuildContext; + + /** + * @member {module:@ui5/builder.tasks.TaskUtil~StandardBuildTags} + * @public + */ + this.STANDARD_TAGS = this._projectBuildContext.STANDARD_TAGS; + } + + /** + * Stores a tag with value for a given resource's path. Note that the tag is independent of the supplied + * resource instance. For two resource instances with the same path, the same tag value is returned. + * If the path of a resource is changed, any tag information previously stored for that resource is lost. + * + *

+ * This method is only available to custom task extensions defining + * Specification Version 2.2 and above. + * + * @param {module:@ui5/fs.Resource} resource The resource the tag should be stored for + * @param {string} tag Name of the tag. + * Currently only the [STANDARD_TAGS]{@link module:@ui5/builder.tasks.TaskUtil#STANDARD_TAGS} are allowed + * @param {string|boolean|integer} [value=true] Tag value. Must be primitive + * @public + */ + setTag(resource, tag, value) { + return this._projectBuildContext.getResourceTagCollection().setTag(resource, tag, value); + } + + /** + * Retrieves the value for a stored tag. If no value is stored, undefined is returned. + * + *

+ * This method is only available to custom task extensions defining + * Specification Version 2.2 and above. + * + * @param {module:@ui5/fs.Resource} resource The resource the tag should be retrieved for + * @param {string} tag Name of the tag + * @returns {string|boolean|integer|undefined} Tag value for the given resource. + * undefined if no value is available + * @public + */ + getTag(resource, tag) { + return this._projectBuildContext.getResourceTagCollection().getTag(resource, tag); + } + + /** + * Clears the value of a tag stored for the given resource's path. + * It's like the tag was never set for that resource. + * + *

+ * This method is only available to custom task extensions defining + * Specification Version 2.2 and above. + * + * @param {module:@ui5/fs.Resource} resource The resource the tag should be cleared for + * @param {string} tag Tag + * @public + */ + clearTag(resource, tag) { + return this._projectBuildContext.getResourceTagCollection().clearTag(resource, tag); + } + + /** + * Check whether the project currently being built is the root project. + * + *

+ * This method is only available to custom task extensions defining + * Specification Version 2.2 and above. + * + * @returns {boolean} true if the currently built project is the root project + * @public + */ + isRootProject() { + return this._projectBuildContext.isRootProject(); + } + + /** + * Register a function that must be executed once the build is finished. This can be used to, for example, + * clean up files temporarily created on the file system. If the callback returns a Promise, it will be waited for. + * It will also be executed in cases where the build has failed or has been aborted. + * + *

+ * This method is only available to custom task extensions defining + * Specification Version 2.2 and above. + * + * @param {Function} callback Callback to register. If it returns a Promise, it will be waited for + * @public + */ + registerCleanupTask(callback) { + return this._projectBuildContext.registerCleanupTask(callback); + } + + /** + * Get an interface to an instance of this class that only provides those functions + * that are supported by the given custom task extension specification version. + * + * @param {string} specVersion Specification version of custom task extension + * @returns {object} An object with bound instance methods supported by the given specification version + */ + getInterface(specVersion) { + if (["0.1", "1.0", "1.1", "2.0", "2.1"].includes(specVersion)) { + return undefined; + } + + const baseInterface = { + STANDARD_TAGS: this.STANDARD_TAGS, + setTag: this.setTag.bind(this), + clearTag: this.clearTag.bind(this), + getTag: this.getTag.bind(this), + isRootProject: this.isRootProject.bind(this), + registerCleanupTask: this.registerCleanupTask.bind(this) + }; + switch (specVersion) { + case "2.2": + return baseInterface; + default: + throw new Error(`TaskUtil: Unknown or unsupported Specification Version ${specVersion}`); + } + } +} + +module.exports = TaskUtil; diff --git a/lib/tasks/buildThemes.js b/lib/tasks/buildThemes.js index 0dd03688c..1df0bad8b 100644 --- a/lib/tasks/buildThemes.js +++ b/lib/tasks/buildThemes.js @@ -1,66 +1,135 @@ +const path = require("path"); const themeBuilder = require("../processors/themeBuilder"); const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized; const fsInterface = require("@ui5/fs").fsInterface; +const log = require("@ui5/logger").getLogger("builder:tasks:buildThemes"); /** * Task to build a library theme. * * @public * @alias module:@ui5/builder.tasks.buildThemes - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options - * @param {string} parameters.options.pattern Pattern to locate the files to be processed + * @param {object} parameters.options Options + * @param {string} parameters.options.projectName Project name + * @param {string} parameters.options.inputPattern Search pattern for *.less files to be built + * @param {string} [parameters.options.librariesPattern] Search pattern for .library files + * @param {string} [parameters.options.themesPattern] Search pattern for sap.ui.core theme folders + * @param {boolean} [parameters.options.compress=true] + * @param {boolean} [parameters.options.cssVariables=false] * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { +module.exports = async function({ + workspace, dependencies, + options: { + projectName, inputPattern, librariesPattern, themesPattern, compress, cssVariables + } +}) { const combo = new ReaderCollectionPrioritized({ - name: `theme - prioritize workspace over dependencies: ${options.projectName}`, + name: `theme - prioritize workspace over dependencies: ${projectName}`, readers: [workspace, dependencies] }); - const promises = [workspace.byGlob(options.inputPattern)]; - if (options.librariesPattern) { + compress = compress === undefined ? true : compress; + + const pAllResources = workspace.byGlob(inputPattern); + let pAvailableLibraries; + let pAvailableThemes; + if (librariesPattern) { // If a librariesPattern is given // we will use it to reduce the set of libraries a theme will be built for - promises.push(combo.byGlob(options.librariesPattern)); + pAvailableLibraries = combo.byGlob(librariesPattern); + } + if (themesPattern) { + // If a themesPattern is given + // we will use it to reduce the set of themes that will be built + pAvailableThemes = combo.byGlob(themesPattern, {nodir: false}); } - return Promise.all(promises).then(([allResources, availableLibraries]) => { - if (!availableLibraries || availableLibraries.length === 0) { - // Try to build all themes - return allResources; - } - /* Don't try to build themes for libraries that are not available - (maybe replace this with something more aware of which dependencies are optional and therefore - legitimately missing and which not (fault case)) + /* Don't try to build themes for libraries that are not available + (maybe replace this with something more aware of which dependencies are optional and therefore + legitimately missing and which not (fault case)) */ - const availableLibraryPaths = availableLibraries.map((resource) => { + let availableLibraries; + if (pAvailableLibraries) { + availableLibraries = (await pAvailableLibraries).map((resource) => { return resource.getPath().replace(/[^/]*\.library/i, ""); }); + } + let availableThemes; + if (pAvailableThemes) { + availableThemes = (await pAvailableThemes) + .filter((resource) => resource.getStatInfo().isDirectory()) + .map((resource) => { + return path.basename(resource.getPath()); + }); + } - const isAvailable = function(resource) { - for (let i = availableLibraryPaths.length - 1; i >= 0; i--) { - if (resource.getPath().indexOf(availableLibraryPaths[i]) === 0) { - return true; + let allResources = await pAllResources; + + const isAvailable = function(resource) { + let libraryAvailable = false; + let themeAvailable = false; + const resourcePath = resource.getPath(); + const themeName = path.basename(path.dirname(resourcePath)); + + if (!availableLibraries || availableLibraries.length === 0) { + libraryAvailable = true; // If no libraries are found, build themes for all libraries + } else { + for (let i = availableLibraries.length - 1; i >= 0; i--) { + if (resourcePath.startsWith(availableLibraries[i])) { + libraryAvailable = true; } } - return false; - }; + } + + if (!availableThemes || availableThemes.length === 0) { + themeAvailable = true; // If no themes are found, build all themes + } else { + themeAvailable = availableThemes.includes(themeName); + } - return allResources.filter(isAvailable); - }).then((resources) => { - return themeBuilder({ - resources, - fs: fsInterface(combo), - options: { - compress: true + if (log.isLevelEnabled("verbose")) { + if (!libraryAvailable) { + log.verbose(`Skipping ${resourcePath}: Library is not available`); } - }); - }).then((processedResources) => { - return Promise.all(processedResources.map((resource) => { - return workspace.write(resource); - })); + if (!themeAvailable) { + log.verbose(`Skipping ${resourcePath}: sap.ui.core theme '${themeName}' is not available. ` + + "If you experience missing themes, check whether you have added the corresponding theme " + + "library to your projects dependencies and make sure that your custom themes contain " + + "resources for the sap.ui.core namespace."); + } + } + + // Only build if library and theme are available + return libraryAvailable && themeAvailable; + }; + + if (availableLibraries || availableThemes) { + if (log.isLevelEnabled("verbose")) { + log.verbose("Filtering themes to be built:"); + if (availableLibraries) { + log.verbose(`Available libraries: ${availableLibraries.join(", ")}`); + } + if (availableThemes) { + log.verbose(`Available sap.ui.core themes: ${availableThemes.join(", ")}`); + } + } + allResources = allResources.filter(isAvailable); + } + + const processedResources = await themeBuilder({ + resources: allResources, + fs: fsInterface(combo), + options: { + compress, + cssVariables: !!cssVariables + } }); + + await Promise.all(processedResources.map((resource) => { + return workspace.write(resource); + })); }; diff --git a/lib/tasks/bundlers/generateBundle.js b/lib/tasks/bundlers/generateBundle.js index 6a44a0506..49698e4ba 100644 --- a/lib/tasks/bundlers/generateBundle.js +++ b/lib/tasks/bundlers/generateBundle.js @@ -6,40 +6,38 @@ const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritiz * * @public * @alias module:@ui5/builder.tasks.generateBundle - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Collection} parameters.dependencies Collection to read dependency files - * @param {Object} parameters.options Options + * @param {module:@ui5/fs.ReaderCollection} parameters.dependencies Collection to read dependency files + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name - * @param {Object} parameters.options.bundleDefinition Module bundle definition - * @param {string} parameters.options.bundleDefinition.name The module bundle name - * @param {string[]} [parameters.options.bundleDefinition.defaultFileTypes=[".js", ".fragment.xml", ".view.xml", ".properties", ".json"]] List of default file types to be included in the bundle - * @param {ModuleBundleDefinitionSection[]} parameters.options.bundleDefinition.sections List of module bundle definition sections - * @param {Object} parameters.options.bundleOptions Module bundle options - * @param {boolean} [parameters.options.bundleOptions.optimize=false] If set to 'true' the module bundle gets minified - * @param {boolean} [parameters.options.bundleOptions.decorateBootstrapModule=true] If set to 'false', the module won't be decorated with an optimization marker - * @param {boolean} [parameters.options.bundleOptions.addTryCatchRestartWrapper=false] Whether to wrap bootable module bundles with a try/catch to filter out "Restart" errors - * @param {boolean} [parameters.options.bundleOptions.usePredefineCalls=false] If set to 'true', sap.ui.predefine is used for UI5 modules - * @param {number} [parameters.options.bundleOptions.numberOfParts=1] The number of parts the module bundle should be splitted + * @param {ModuleBundleDefinition} parameters.options.bundleDefinition Module bundle definition + * @param {ModuleBundleOptions} parameters.options.bundleOptions Module bundle options * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { +module.exports = function({ + workspace, dependencies, taskUtil, options: {projectName, bundleDefinition, bundleOptions} +}) { const combo = new ReaderCollectionPrioritized({ - name: `libraryBundler - prioritize workspace over dependencies: ${options.projectName}`, + name: `libraryBundler - prioritize workspace over dependencies: ${projectName}`, readers: [workspace, dependencies] }); return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library}").then((resources) => { return moduleBundler({ options: { - bundleDefinition: options.bundleDefinition, - bundleOptions: options.bundleOptions + bundleDefinition, + bundleOptions }, resources }).then((bundles) => { - bundles.forEach((bundle) => { - workspace.write(bundle); - }); + return Promise.all(bundles.map((bundle) => { + if (taskUtil) { + taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle); + } + return workspace.write(bundle); + })); }); }); }; diff --git a/lib/tasks/bundlers/generateComponentPreload.js b/lib/tasks/bundlers/generateComponentPreload.js index 226a59fcc..dd14942af 100644 --- a/lib/tasks/bundlers/generateComponentPreload.js +++ b/lib/tasks/bundlers/generateComponentPreload.js @@ -1,5 +1,6 @@ const path = require("path"); const moduleBundler = require("../../processors/bundlers/moduleBundler"); +const log = require("@ui5/logger").getLogger("builder:tasks:bundlers:generateComponentPreload"); const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized; /** @@ -7,45 +8,50 @@ const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritiz * * @public * @alias module:@ui5/builder.tasks.generateComponentPreload - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @param {Array} [parameters.options.paths] Array of paths (or glob patterns) for component files * @param {Array} [parameters.options.namespaces] Array of component namespaces * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { +module.exports = function({workspace, dependencies, taskUtil, options: {projectName, paths, namespaces}}) { const combo = new ReaderCollectionPrioritized({ - name: `generateComponentPreload - prioritize workspace over dependencies: ${options.projectName}`, + name: `generateComponentPreload - prioritize workspace over dependencies: ${projectName}`, readers: [workspace, dependencies] }); return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library}") .then(async (resources) => { - let namespaces = []; - if (options.paths) { - namespaces = await Promise.all(options.paths.map(async (componentPath) => { - const components = await combo.byGlob("/resources/" + componentPath); + let allNamespaces = []; + if (paths) { + allNamespaces = await Promise.all(paths.map(async (componentPath) => { + const globPath = "/resources/" + componentPath; + log.verbose(`Globbing for Components directories with configured path ${globPath}...`); + const components = await combo.byGlob(globPath); return components.map((component) => { - return path.dirname(component.getPath()).replace(/^\/resources\//i, ""); + const compDir = path.dirname(component.getPath()).replace(/^\/resources\//i, ""); + log.verbose(`Found component namespace ${compDir}`); + return compDir; }); })); } - if (options.namespaces) { - namespaces.push(...options.namespaces); + if (namespaces) { + allNamespaces.push(...namespaces); } - namespaces = Array.prototype.concat.apply([], namespaces); + allNamespaces = Array.prototype.concat.apply([], allNamespaces); // As this task is often called with a single namespace, also check // for bad calls like "namespaces: [undefined]" - if (!namespaces || !namespaces.length || !namespaces[0]) { + if (!allNamespaces || !allNamespaces.length || !allNamespaces[0]) { throw new Error("generateComponentPreload: No component namespace(s) " + - `found for project: ${options.projectName}`); + `found for project: ${projectName}`); } - return Promise.all(namespaces.map((namespace) => { + return Promise.all(allNamespaces.map((namespace) => { const filters = [ `${namespace}/`, `!${namespace}/test/`, @@ -53,12 +59,13 @@ module.exports = function({workspace, dependencies, options}) { ]; // Exclude other namespaces - namespaces.forEach((ns) => { + allNamespaces.forEach((ns) => { if (ns !== namespace && ns.indexOf(namespace) === 0) { filters.push(`!${ns}/`); } }); + log.verbose(`Requesting Component-preload.js for namespace ${namespace}...`); return moduleBundler({ resources, options: { @@ -74,6 +81,10 @@ module.exports = function({workspace, dependencies, options}) { renderer: false } ] + }, + bundleOptions: { + ignoreMissingModules: true, + optimize: true } } }); @@ -81,6 +92,9 @@ module.exports = function({workspace, dependencies, options}) { }) .then((processedResources) => { return Promise.all(processedResources.map((resource) => { + if (taskUtil) { + taskUtil.setTag(resource[0], taskUtil.STANDARD_TAGS.IsBundle); + } return workspace.write(resource[0]); })); }); diff --git a/lib/tasks/bundlers/generateFlexChangesBundle.js b/lib/tasks/bundlers/generateFlexChangesBundle.js index b45fdfad5..81d1f88b2 100644 --- a/lib/tasks/bundlers/generateFlexChangesBundle.js +++ b/lib/tasks/bundlers/generateFlexChangesBundle.js @@ -6,21 +6,24 @@ const flexChangesBundler = require("../../processors/bundlers/flexChangesBundler * at runtime. * If a change bundle is created, "sap.ui.fl" is added as a dependency to the manifest.json if not already present - * if the dependency is already listed but lazy-loaded, lazy loading is disabled. + * If minUI5Version >= 1.73 flexibility-bundle.json will be create. + * If there are control variants and minUI5Version < 1.73 build will break and throw an error. * * @public * @alias module:@ui5/builder.tasks.generateFlexChangesBundle - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} [parameters.options] Options + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} [parameters.options] Options * @param {string} [parameters.options.namespace] Application Namespace * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, options}) { +module.exports = async function({workspace, taskUtil, options: {namespace}}) { // Use the given namespace if available, otherwise use no namespace // (e.g. in case no manifest.json is present) let pathPrefix = ""; - if (options && options.namespace) { - pathPrefix = `/resources/${options.namespace}`; + if (namespace) { + pathPrefix = `/resources/${namespace}`; } function updateJson(data) { @@ -51,26 +54,46 @@ module.exports = function({workspace, options}) { await workspace.write(manifestResource); } + async function readManifestMinUI5Version() { + const manifestResource = await workspace.byPath(`${pathPrefix}/manifest.json`); + const manifestContent = JSON.parse(await manifestResource.getString()); + + manifestContent["sap.ui5"] = manifestContent["sap.ui5"] || {}; + manifestContent["sap.ui5"].dependencies = manifestContent["sap.ui5"].dependencies || {}; + return manifestContent["sap.ui5"].dependencies.minUI5Version = + manifestContent["sap.ui5"].dependencies.minUI5Version || ""; + } + log.verbose("Collecting flexibility changes"); - return workspace.byGlob(`${pathPrefix}/changes/*.change`) - .then((allResources) => { - return flexChangesBundler({ - resources: allResources, - options: { - namespace: options.namespace, - pathPrefix: pathPrefix - } - }); - }) - .then((processedResources) => { - return Promise.all(processedResources.map((resource) => { - log.verbose("Writing flexibility changes bundle"); - return workspace.write(resource); - })).then(async () => { - // Add the sap.ui.fl dependency if a bundle has been created - if (processedResources.length > 0) { - await updateFLdependency(); - } - }); + const allResources = await workspace.byGlob( + `${pathPrefix}/changes/*.{change,variant,ctrl_variant,ctrl_variant_change,ctrl_variant_management_change}`); + if (allResources.length > 0) { + const version = await readManifestMinUI5Version(); + let hasFlexBundleVersion = false; + if (parseFloat(version) >= 1.73) { + hasFlexBundleVersion = true; + } + const processedResources = await flexChangesBundler({ + resources: allResources, + options: { + pathPrefix, + hasFlexBundleVersion + } }); + await Promise.all(processedResources.map((resource) => { + log.verbose("Writing flexibility changes bundle"); + return workspace.write(resource); + })); + // Add the sap.ui.fl dependency if a bundle has been created + if (processedResources.length > 0) { + await updateFLdependency(); + } + + // Do not write bundled source files to build result + if (taskUtil) { + allResources.forEach((resource) => { + taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult); + }); + } + } }; diff --git a/lib/tasks/bundlers/generateLibraryPreload.js b/lib/tasks/bundlers/generateLibraryPreload.js index e940617a1..aabcd8a3c 100644 --- a/lib/tasks/bundlers/generateLibraryPreload.js +++ b/lib/tasks/bundlers/generateLibraryPreload.js @@ -2,12 +2,38 @@ const log = require("@ui5/logger").getLogger("builder:tasks:bundlers:generateLib const moduleBundler = require("../../processors/bundlers/moduleBundler"); const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized; +const DEFAULT_FILE_TYPES = [ + ".js", + ".control.xml", // XMLComposite + ".fragment.html", + ".fragment.json", + ".fragment.xml", + ".view.html", + ".view.json", + ".view.xml", + ".properties", + ".json" +]; + +function getDefaultLibraryPreloadFilters(namespace) { + return [ + `${namespace}/`, + `!${namespace}/.library`, + `!${namespace}/*-preload.js`, // exclude all bundles + `!${namespace}/designtime/`, + `!${namespace}/**/*.designtime.js`, + `!${namespace}/**/*.support.js`, + `!${namespace}/themes/`, + `!${namespace}/messagebundle*` + ]; +} + function getBundleDefinition(namespace) { // TODO: move to config of actual core project if (namespace === "sap/ui/core") { return { name: `${namespace}/library-preload.js`, - defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"], + defaultFileTypes: DEFAULT_FILE_TYPES, sections: [ { // exclude the content of sap-ui-core by declaring it as 'provided' @@ -21,15 +47,9 @@ function getBundleDefinition(namespace) { { mode: "preload", filters: [ - `${namespace}/`, - `!${namespace}/.library`, - `!${namespace}/designtime/`, - `!${namespace}/**/*.designtime.js`, - `!${namespace}/**/*.support.js`, - `!${namespace}/themes/`, - `!${namespace}/cldr/`, - `!${namespace}/messagebundle*`, + ...getDefaultLibraryPreloadFilters(namespace), + `!${namespace}/cldr/`, "*.js", "sap/base/", "sap/ui/base/", @@ -42,7 +62,7 @@ function getBundleDefinition(namespace) { // include only thirdparty that is very likely to be used "sap/ui/thirdparty/crossroads.js", - "sap/ui/thirdparty/caja-htmlsanitizer.js", + "sap/ui/thirdparty/caja-html-sanitizer.js", "sap/ui/thirdparty/hasher.js", "sap/ui/thirdparty/signals.js", "sap/ui/thirdparty/jquery-mobile-custom.js", @@ -65,27 +85,101 @@ function getBundleDefinition(namespace) { } return { name: `${namespace}/library-preload.js`, - defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"], + defaultFileTypes: DEFAULT_FILE_TYPES, + sections: [ + { + mode: "preload", + filters: getDefaultLibraryPreloadFilters(namespace), + resolve: false, + resolveConditional: false, + renderer: true + } + ] + }; +} + +function getDesigntimeBundleDefinition(namespace) { + return { + name: `${namespace}/designtime/library-preload.designtime.js`, + defaultFileTypes: DEFAULT_FILE_TYPES, sections: [ { mode: "preload", filters: [ - `${namespace}/`, - `!${namespace}/.library`, - `!${namespace}/designtime/`, - `!${namespace}/**/*.designtime.js`, - `!${namespace}/**/*.support.js`, - `!${namespace}/themes/`, - `!${namespace}/messagebundle*` + `${namespace}/**/*.designtime.js`, + `${namespace}/designtime/`, + `!${namespace}/**/*-preload.designtime.js`, + `!${namespace}/designtime/**/*.properties`, + `!${namespace}/designtime/**/*.svg`, + `!${namespace}/designtime/**/*.xml` ], resolve: false, resolveConditional: false, - renderer: true + renderer: false + } + ] + }; +} + +function getSupportFilesBundleDefinition(namespace) { + return { + name: `${namespace}/library-preload.support.js`, + defaultFileTypes: DEFAULT_FILE_TYPES, + sections: [ + { + mode: "preload", + filters: [ + `${namespace}/**/*.support.js`, + `!${namespace}/**/*-preload.support.js` + ], + resolve: false, + resolveConditional: false, + renderer: false } ] }; } +function createLibraryBundles(libraryNamespace, resources) { + return Promise.all([ + moduleBundler({ + options: { + bundleDefinition: getBundleDefinition(libraryNamespace), + bundleOptions: { + optimize: true, + usePredefineCalls: true, + ignoreMissingModules: true + } + }, + resources + }), + moduleBundler({ + options: { + bundleDefinition: getDesigntimeBundleDefinition(libraryNamespace), + bundleOptions: { + optimize: true, + usePredefineCalls: true, + ignoreMissingModules: true, + skipIfEmpty: true + } + }, + resources + }), + moduleBundler({ + options: { + bundleDefinition: getSupportFilesBundleDefinition(libraryNamespace), + bundleOptions: { + optimize: false, + usePredefineCalls: true, + ignoreMissingModules: true, + skipIfEmpty: true + } + }, + resources + }) + ]); +} + function getModuleBundlerOptions(config) { const moduleBundlerOptions = {}; @@ -161,16 +255,17 @@ function getSapUiCoreBunDef(name, filters, preload) { * * @public * @alias module:@ui5/builder.tasks.generateLibraryPreload - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { +module.exports = function({workspace, dependencies, taskUtil, options: {projectName}}) { const combo = new ReaderCollectionPrioritized({ - name: `libraryBundler - prioritize workspace over dependencies: ${options.projectName}`, + name: `libraryBundler - prioritize workspace over dependencies: ${projectName}`, readers: [workspace, dependencies] }); @@ -181,7 +276,7 @@ module.exports = function({workspace, dependencies, options}) { // Create sap-ui-core.js // TODO: move to config of actual core project - if (options.projectName === "sap.ui.core") { + if (projectName === "sap.ui.core") { // Filter out sap-ui-core.js from further uglification/replacement processors // to prevent them from overwriting it resources = resources.filter((resource) => { @@ -208,16 +303,25 @@ module.exports = function({workspace, dependencies, options}) { resources }), moduleBundler({ - options: getModuleBundlerOptions({name: "sap-ui-core-nojQuery.js", filters, preload: true, provided: true}), + options: getModuleBundlerOptions({ + name: "sap-ui-core-nojQuery.js", filters, preload: true, provided: true + }), resources }), moduleBundler({ - options: getModuleBundlerOptions({name: "sap-ui-core-nojQuery-dbg.js", filters, preload: false, provided: true}), + options: getModuleBundlerOptions({ + name: "sap-ui-core-nojQuery-dbg.js", filters, preload: false, provided: true + }), resources }), ]).then((results) => { const bundles = Array.prototype.concat.apply([], results); - return Promise.all(bundles.map((bundle) => workspace.write(bundle))); + return Promise.all(bundles.map((bundle) => { + if (taskUtil) { + taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle); + } + return workspace.write(bundle); + })); }); } else { p = Promise.resolve(); @@ -229,13 +333,16 @@ module.exports = function({workspace, dependencies, options}) { return libraryIndicatorResources; } else { // Fallback to "library.js" as library indicator - log.verbose(`Could not find a ".library" file for project ${options.projectName}, falling back to "library.js".`); + log.verbose( + `Could not find a ".library" file for project ${projectName}, falling back to "library.js".`); return workspace.byGlob("/resources/**/library.js"); } }).then((libraryIndicatorResources) => { if (libraryIndicatorResources.length < 1) { // No library found - nothing to do - log.verbose(`Could not find a ".library" or "library.js" file for project ${options.projectName}. Skipping library preload bundling.`); + log.verbose( + `Could not find a ".library" or "library.js" file for project ${projectName}. ` + + `Skipping library preload bundling.`); return; } @@ -249,23 +356,22 @@ module.exports = function({workspace, dependencies, options}) { const libraryNamespaceMatch = libraryIndicatorPath.match(libraryNamespacePattern); if (libraryNamespaceMatch && libraryNamespaceMatch[1]) { const libraryNamespace = libraryNamespaceMatch[1]; - return moduleBundler({ - options: { - bundleDefinition: getBundleDefinition(libraryNamespace), - bundleOptions: { - optimize: true, - usePredefineCalls: true - } - }, - resources - }).then(([bundle]) => { - if (bundle) { - // console.log(`${libraryNamespace}/library-preload.js bundle created`); - return workspace.write(bundle); - } - }); + return createLibraryBundles(libraryNamespace, resources) + .then((results) => { + const bundles = Array.prototype.concat.apply([], results); + return Promise.all(bundles.map((bundle) => { + if (bundle) { + if (taskUtil) { + taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle); + } + return workspace.write(bundle); + } + })); + }); } else { - log.verbose(`Could not determine library namespace from file "${libraryIndicatorPath}" for project ${options.projectName}. Skipping library preload bundling.`); + log.verbose( + `Could not determine library namespace from file "${libraryIndicatorPath}" ` + + `for project ${projectName}. Skipping library preload bundling.`); return Promise.resolve(); } })); diff --git a/lib/tasks/bundlers/generateManifestBundle.js b/lib/tasks/bundlers/generateManifestBundle.js index 4f740e139..38718e2c3 100644 --- a/lib/tasks/bundlers/generateManifestBundle.js +++ b/lib/tasks/bundlers/generateManifestBundle.js @@ -4,26 +4,33 @@ const DESCRIPTOR = "manifest.json"; const PROPERTIES_EXT = ".properties"; const BUNDLE_NAME = "manifest-bundle.zip"; +/** + * + * @public + * @typedef {object} ManifestBundlerOptions + * @property {string} projectName Project Name + * @property {string} namespace Namespace + */ + /** * Task for manifestBundler. * * @public * @alias module:@ui5/builder.tasks.generateManifestBundle - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} parameters.options Options - * @param {string} parameters.options.projectName Project name - * @param {string} parameters.options.namespace Namespace of the application/library + * @param {ManifestBundlerOptions} parameters.options Options * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, options}) { - if (!options || !options.projectName || !options.namespace) { +module.exports = async function({workspace, options = {}}) { + const {projectName, namespace} = options; + if (!projectName || !namespace) { throw new Error("[generateManifestBundle]: One or more mandatory options not provided"); } - const allResources = await workspace.byGlob(`/resources/${options.namespace}/**/{${DESCRIPTOR},*${PROPERTIES_EXT}}`); + const allResources = await workspace.byGlob(`/resources/${namespace}/**/{${DESCRIPTOR},*${PROPERTIES_EXT}}`); if (allResources.length === 0) { - log.verbose(`Could not find a "${DESCRIPTOR}" file for project ${options.projectName}, ` + + log.verbose(`Could not find a "${DESCRIPTOR}" file for project ${projectName}, ` + `creation of "${BUNDLE_NAME}" is skipped!`); return; } @@ -34,7 +41,7 @@ module.exports = async function({workspace, options}) { descriptor: DESCRIPTOR, propertiesExtension: PROPERTIES_EXT, bundleName: BUNDLE_NAME, - namespace: options.namespace + namespace } }); diff --git a/lib/tasks/bundlers/generateStandaloneAppBundle.js b/lib/tasks/bundlers/generateStandaloneAppBundle.js index 5a812aa73..ecb1bfae5 100644 --- a/lib/tasks/bundlers/generateStandaloneAppBundle.js +++ b/lib/tasks/bundlers/generateStandaloneAppBundle.js @@ -49,17 +49,18 @@ function getBundleDefinition(config) { * * @public * @alias module:@ui5/builder.tasks.generateStandaloneAppBundle - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @param {string} [parameters.options.namespace] Project namespace * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, dependencies, options}) { - if (!options.namespace) { - log.warn(`Namespace of project ${options.projectName} is not known. Self contained bundling is currently ` + +module.exports = async function({workspace, dependencies, taskUtil, options: {projectName, namespace}}) { + if (!namespace) { + log.warn(`Namespace of project ${projectName} is not known. Self contained bundling is currently ` + `unable to generate complete bundles for such projects.`); } @@ -88,7 +89,7 @@ module.exports = async function({workspace, dependencies, options}) { bundleDefinition: getBundleDefinition({ name: "sap-ui-custom.js", filters, - namespace: options.namespace, + namespace, preloadSection: true }) } @@ -99,7 +100,7 @@ module.exports = async function({workspace, dependencies, options}) { bundleDefinition: getBundleDefinition({ name: "sap-ui-custom-dbg.js", filters, - namespace: options.namespace + namespace }), bundleOptions: { optimize: false @@ -108,6 +109,11 @@ module.exports = async function({workspace, dependencies, options}) { }) ]).then((results) => { const bundles = Array.prototype.concat.apply([], results); - return Promise.all(bundles.map((resource) => workspace.write(resource))); + return Promise.all(bundles.map((resource) => { + if (taskUtil) { + taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.IsBundle); + } + return workspace.write(resource); + })); }); }; diff --git a/lib/tasks/createDebugFiles.js b/lib/tasks/createDebugFiles.js index b2e1274b7..341e0d548 100644 --- a/lib/tasks/createDebugFiles.js +++ b/lib/tasks/createDebugFiles.js @@ -6,18 +6,18 @@ const fsInterface = require("@ui5/fs").fsInterface; * * @public * @alias module:@ui5/builder.tasks.createDebugFiles - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} [parameters.options] Options - * @param {string} [parameters.options.pattern] Pattern to locate the files to be processed + * @param {object} parameters.options Options + * @param {string} parameters.options.pattern Pattern to locate the files to be processed * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, options}) { +module.exports = async function({workspace, options: {pattern}}) { let allResources; if (workspace.byGlobSource) { // API only available on duplex collections - allResources = await workspace.byGlobSource(options.pattern); + allResources = await workspace.byGlobSource(pattern); } else { - allResources = await workspace.byGlob(options.pattern); + allResources = await workspace.byGlob(pattern); } return dbg({ fs: fsInterface(workspace), diff --git a/lib/tasks/escapeNonAsciiCharacters.js b/lib/tasks/escapeNonAsciiCharacters.js index 5acb377b6..294565c46 100644 --- a/lib/tasks/escapeNonAsciiCharacters.js +++ b/lib/tasks/escapeNonAsciiCharacters.js @@ -5,24 +5,24 @@ const nonAsciiEscaper = require("../processors/nonAsciiEscaper"); * * @public * @alias module:@ui5/builder.tasks.escapeNonAsciiCharacters - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.pattern Glob pattern to locate the files to be processed * @param {string} parameters.options.encoding source file encoding either "UTF-8" or "ISO-8859-1" * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, options}) { - if (!options.encoding) { +module.exports = async function({workspace, options: {pattern, encoding}}) { + if (!encoding) { throw new Error("[escapeNonAsciiCharacters] Mandatory option 'encoding' not provided"); } - const allResources = await workspace.byGlob(options.pattern); + const allResources = await workspace.byGlob(pattern); const processedResources = await nonAsciiEscaper({ resources: allResources, options: { - encoding: nonAsciiEscaper.getEncodingFromAlias(options.encoding) + encoding: nonAsciiEscaper.getEncodingFromAlias(encoding) } }); diff --git a/lib/tasks/generateCachebusterInfo.js b/lib/tasks/generateCachebusterInfo.js index fe4d7cddc..91cd6d77c 100644 --- a/lib/tasks/generateCachebusterInfo.js +++ b/lib/tasks/generateCachebusterInfo.js @@ -32,27 +32,27 @@ function getSigner(type) { * * @public * @alias module:@ui5/builder.tasks.generateCachebusterInfo - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.namespace Namespace of the application * @param {string} [parameters.options.signatureType='time'] Type of signature to be used ('time' or 'hash') * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { - return workspace.byGlob(`/resources/${options.namespace}/**/*`) +module.exports = function({workspace, dependencies, options: {namespace, signatureType}}) { + return workspace.byGlob(`/resources/${namespace}/**/*`) .then(async (resources) => { const cachebusterInfo = {}; - const regex = new RegExp(`^/resources/${options.namespace}/`); - const signer = getSigner(options.signatureType); + const regex = new RegExp(`^/resources/${namespace}/`); + const signer = getSigner(signatureType); await Promise.all(resources.map(async (resource) => { const normalizedPath = resource.getPath().replace(regex, ""); cachebusterInfo[normalizedPath] = await signer(resource); })); const cachebusterInfoResource = resourceFactory.createResource({ - path: `/resources/${options.namespace}/sap-ui-cachebuster-info.json`, + path: `/resources/${namespace}/sap-ui-cachebuster-info.json`, string: JSON.stringify(cachebusterInfo, null, 2) }); return workspace.write(cachebusterInfoResource); diff --git a/lib/tasks/generateLibraryManifest.js b/lib/tasks/generateLibraryManifest.js index 3e46eb820..015f72e08 100644 --- a/lib/tasks/generateLibraryManifest.js +++ b/lib/tasks/generateLibraryManifest.js @@ -10,16 +10,16 @@ const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritiz * * @public * @alias module:@ui5/builder.tasks.generateLibraryManifest - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { +module.exports = function({workspace, dependencies, options: {projectName}}) { const combo = new ReaderCollectionPrioritized({ - name: `libraryManifestGenerator - prioritize workspace over dependencies: ${options.projectName}`, + name: `libraryManifestGenerator - prioritize workspace over dependencies: ${projectName}`, readers: [workspace, dependencies] }); // Note: @@ -33,7 +33,8 @@ module.exports = function({workspace, dependencies, options}) { return workspace.byGlob("/resources/**/.library").then((libraryIndicatorResources) => { if (libraryIndicatorResources.length < 1) { // No library found - nothing to do - log.verbose(`Could not find a ".library" file for project ${options.projectName}. Skipping library manifest generation.`); + log.verbose(`Could not find a ".library" file for project ${projectName}. ` + + `Skipping library manifest generation.`); return; } @@ -58,7 +59,8 @@ module.exports = function({workspace, dependencies, options}) { } }); } else { - log.verbose(`Could not determine library namespace from file "${libraryIndicatorPath}" for project ${options.projectName}. Skipping library manifest generation.`); + log.verbose(`Could not determine library namespace from file "${libraryIndicatorPath}" ` + + `for project ${projectName}. Skipping library manifest generation.`); return Promise.resolve(); } })); diff --git a/lib/tasks/generateResourcesJson.js b/lib/tasks/generateResourcesJson.js new file mode 100644 index 000000000..bf1d593c2 --- /dev/null +++ b/lib/tasks/generateResourcesJson.js @@ -0,0 +1,125 @@ +"use strict"; + +const resourceListCreator = require("../processors/resourceListCreator"); + +const DEFAULT_EXCLUDES = [ + /* + * exclude mac metadata files + */ + "!**/.DS_Store", + /* + * sap-ui-version.json is not part of the resources + */ + "!/resources/sap-ui-version.json" +]; + +function getCreatorOptions(projectName) { + const creatorOptions = {}; + // TODO: Move configuration into ui5.yaml + if ( projectName === "sap.ui.core" ) { + Object.assign(creatorOptions, { + externalResources: { + "sap/ui/core": [ + "*", + "sap/base/", + "sap/ui/" + ] + }, + mergedResourcesFilters: [ + "jquery-sap*.js", + "sap-ui-core*.js", + "**/Component-preload.js", + "**/library-preload.js", + "**/library-preload-dbg.js", + "**/library-preload.json", + "**/library-all.js", + "**/library-all-dbg.js", + "**/designtime/library-preload.designtime.js", + "**/library-preload.support.js" + ] + }); + } else if ( projectName === "sap.ui.integration" ) { + Object.assign(creatorOptions, { + externalResources: { + "sap/ui/integration": [ + "sap-ui-integration*.js", + ] + } + }); + } + return creatorOptions; +} + +/** + * Task for creating a resources.json file, describing all productive build resources. + * + *

+ * The detailed structure can be found in the documentation: + * {@link https://openui5.hana.ondemand.com/#topic/adcbcf8b50924556ab3f321fcd9353ea} + *

+ * + *

+ * Not supported in combination with task {@link module:@ui5/builder.tasks.generateStandaloneAppBundle}. + * Therefore it is also not supported in combination with self-contained build. + *

+ * + * @example sample resources.json + * const resourcesJson = { + * "_version": "1.1.0", + * "resources": [ + * { + * "name": "Component-preload.js", + * "module": "application/mine/Component-preload.js", + * "size": 3746, + * "merged": true, + * "included": [ + * "application/mine/Component.js", + * "application/mine/changes/coding/MyExtension.js", + * "application/mine/changes/flexibility-bundle.json", + * "application/mine/changes/fragments/MyFragment.fragment.xml", + * "application/mine/manifest.json" + * ] + * }, + * { + * "name": "resources.json", + * "size": 1870 + * }, + * { + * "name": "rules/Button-dbg.support.js", + * "module": "application/mine/rules/Button.support.js", + * "size": 211, + * "format": "raw", + * "isDebug": true, + * "required": [ + * "application/mine/library.js", + * "sap/ui/core/Control.js" + * ], + * "condRequired": [ + * "application/mine/changeHandler/SplitButton.js", + * "sap/ui/core/format/DateFormat.js" + * ], + * "dynRequired": true, + * "support": true + * } + * ] + * }; + * + * @public + * @alias module:@ui5/builder.tasks.generateResourcesJson + * @param {object} parameters Parameters + * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files + * @param {object} parameters.options Options + * @param {string} parameters.options.projectName Project name + * @returns {Promise} Promise resolving with undefined once data has been written + */ +module.exports = async function({workspace, options: {projectName}}) { + const resources = await workspace.byGlob(["/resources/**/*.*"].concat(DEFAULT_EXCLUDES)); + + const resourceLists = await resourceListCreator({ + resources, + options: getCreatorOptions(projectName) + }); + await Promise.all( + resourceLists.map((resourceList) => workspace.write(resourceList)) + ); +}; diff --git a/lib/tasks/generateVersionInfo.js b/lib/tasks/generateVersionInfo.js index c74045669..f60a69ced 100644 --- a/lib/tasks/generateVersionInfo.js +++ b/lib/tasks/generateVersionInfo.js @@ -5,20 +5,21 @@ const versionInfoGenerator = require("../processors/versionInfoGenerator"); * * @public * @alias module:@ui5/builder.tasks.generateVersionInfo - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options - * @param {Object} parameters.options.rootProject DuplexCollection to read and write files + * @param {object} parameters.options Options + * @param {string} parameters.options.pattern Glob pattern for .library resources + * @param {object} parameters.options.rootProject DuplexCollection to read and write files * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, dependencies, options}) { - return dependencies.byGlob(options.pattern) +module.exports = function({workspace, dependencies, options: {rootProject, pattern}}) { + return dependencies.byGlob(pattern) .then((resources) => { return versionInfoGenerator({ options: { - rootProjectName: options.rootProject.metadata.name, - rootProjectVersion: options.rootProject.version, + rootProjectName: rootProject.metadata.name, + rootProjectVersion: rootProject.version, libraryInfos: resources.map((dotLibResource) => { return { name: dotLibResource._project.metadata.name, diff --git a/lib/tasks/jsdoc/executeJsdocSdkTransformation.js b/lib/tasks/jsdoc/executeJsdocSdkTransformation.js index 55226db7d..c3e154947 100644 --- a/lib/tasks/jsdoc/executeJsdocSdkTransformation.js +++ b/lib/tasks/jsdoc/executeJsdocSdkTransformation.js @@ -10,42 +10,44 @@ const sdkTransformer = require("../../processors/jsdoc/sdkTransformer"); * * @public * @alias module:@ui5/builder.tasks.executeJsdocSdkTransformation - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string|Array} parameters.options.dotLibraryPattern Pattern to locate the .library resource to be processed * @param {string} parameters.options.projectName Project name * @returns {Promise} Promise resolving with undefined once data has been written */ -const executeJsdocSdkTransformation = async function({workspace, dependencies, options} = {}) { - if (!options || !options.projectName || !options.dotLibraryPattern) { +const executeJsdocSdkTransformation = async function( + {workspace, dependencies, options: {projectName, dotLibraryPattern}} = {} +) { + if (!projectName || !dotLibraryPattern) { throw new Error("[executeJsdocSdkTransformation]: One or more mandatory options not provided"); } const [apiJsons, dotLibraries, depApiJsons] = await Promise.all([ workspace.byGlob("/test-resources/**/designtime/api.json"), - workspace.byGlob(options.dotLibraryPattern), + workspace.byGlob(dotLibraryPattern), dependencies.byGlob("/test-resources/**/designtime/api.json") ]); if (!apiJsons.length) { - log.info(`Failed to locate api.json resource for project ${options.projectName}. ` + + log.info(`Failed to locate api.json resource for project ${projectName}. ` + `Skipping SDK Transformation...`); return; } else if (apiJsons.length > 1) { throw new Error(`[executeJsdocSdkTransformation]: Found more than one api.json resources for project ` + - `${options.projectName}.`); + `${projectName}.`); } if (!dotLibraries.length) { throw new Error(`[executeJsdocSdkTransformation]: Failed to locate .library resource for project ` + - `${options.projectName}.`); + `${projectName}.`); } else if (dotLibraries.length > 1) { throw new Error(`[executeJsdocSdkTransformation]: Found more than one .library resources for project ` + - `${options.projectName}.`); + `${projectName}.`); } const combo = new ReaderCollectionPrioritized({ - name: `executeJsdocSdkTransformation - custom workspace + dependencies FS: ${options.projectName}`, + name: `executeJsdocSdkTransformation - custom workspace + dependencies FS: ${projectName}`, readers: [workspace, dependencies] }); diff --git a/lib/tasks/jsdoc/generateApiIndex.js b/lib/tasks/jsdoc/generateApiIndex.js index 005068ec0..58ab46fac 100644 --- a/lib/tasks/jsdoc/generateApiIndex.js +++ b/lib/tasks/jsdoc/generateApiIndex.js @@ -10,19 +10,20 @@ const apiIndexGenerator = require("../../processors/jsdoc/apiIndexGenerator"); * * @public * @alias module:@ui5/builder.tasks.generateApiIndex - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, dependencies, options} = {}) { - if (!options || !options.projectName) { - throw new Error("[generateApiIndex]: One or more mandatory options not provided"); - } +module.exports = async function({ + workspace, + dependencies, + options: {projectName} +}) { const combo = new ReaderCollectionPrioritized({ - name: `generateApiIndex - workspace + dependencies: ${options.projectName}`, + name: `generateApiIndex - workspace + dependencies: ${projectName}`, readers: [workspace, dependencies] }); diff --git a/lib/tasks/jsdoc/generateJsdoc.js b/lib/tasks/jsdoc/generateJsdoc.js index 55a528bcd..0dd5365e7 100644 --- a/lib/tasks/jsdoc/generateJsdoc.js +++ b/lib/tasks/jsdoc/generateJsdoc.js @@ -9,35 +9,55 @@ const rimraf = promisify(require("rimraf")); const jsdocGenerator = require("../../processors/jsdoc/jsdocGenerator"); const {resourceFactory} = require("@ui5/fs"); +/** + * + * @public + * @typedef {object} GenerateJsdocOptions + * @property {string|string[]} pattern Pattern to locate the files to be processed + * @property {string} projectName Project name + * @property {string} namespace Namespace to build (e.g. some/project/name) + * @property {string} version Project version + */ + /** * Task to execute a JSDoc build for UI5 projects * * @public * @alias module:@ui5/builder.tasks.generateJsdoc - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files - * @param {Object} parameters.options Options - * @param {string|Array} parameters.options.pattern Pattern to locate the files to be processed - * @param {string} parameters.options.projectName Project name - * @param {string} parameters.options.namespace Namespace to build (e.g. some/project/name) - * @param {string} parameters.options.version Project version + * @param {GenerateJsdocOptions} parameters.options Options + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} [parameters.buildContext] Internal, deprecated parameter * @returns {Promise} Promise resolving with undefined once data has been written */ -const generateJsdoc = async function({buildContext, workspace, dependencies, options} = {}) { - if (!options || !options.projectName || !options.namespace || !options.version || !options.pattern) { +const generateJsdoc = async function({ + taskUtil, + buildContext, + workspace, + dependencies, + options = {} +}) { + const {projectName, namespace, version, pattern} = /** @type {GenerateJsdocOptions} */ (options); + + if (!projectName || !namespace || !version || !pattern) { throw new Error("[generateJsdoc]: One or more mandatory options not provided"); } const {sourcePath: resourcePath, targetPath, tmpPath, cleanup} = - await generateJsdoc._createTmpDirs(options.projectName); + await generateJsdoc._createTmpDirs(projectName); - buildContext.registerCleanupTask(cleanup); + // TODO 3.0: remove buildContext + const _taskUtil = taskUtil || buildContext; + if (_taskUtil) { + _taskUtil.registerCleanupTask(cleanup); + } const [writtenResourcesCount] = await Promise.all([ generateJsdoc._writeResourcesToDir({ workspace, - pattern: options.pattern, + pattern, targetPath: resourcePath }), generateJsdoc._writeDependencyApisToDir({ @@ -47,8 +67,8 @@ const generateJsdoc = async function({buildContext, workspace, dependencies, opt ]); if (writtenResourcesCount === 0) { - log.info(`Failed to find any input resources for project ${options.projectName} using pattern ` + - `${options.pattern}. Skipping JSDoc generation...`); + log.info(`Failed to find any input resources for project ${projectName} using pattern ` + + `${pattern}. Skipping JSDoc generation...`); return; } @@ -57,9 +77,9 @@ const generateJsdoc = async function({buildContext, workspace, dependencies, opt targetPath, tmpPath, options: { - projectName: options.projectName, - namespace: options.namespace, - version: options.version, + projectName, + namespace, + version, variants: ["apijson"] } }); @@ -74,7 +94,7 @@ const generateJsdoc = async function({buildContext, workspace, dependencies, opt * * @private * @param {string} projectName Project name used for naming the temporary working directory - * @returns {Promise} Promise resolving with sourcePath, targetPath and tmpPath strings + * @returns {Promise} Promise resolving with sourcePath, targetPath and tmpPath strings */ async function createTmpDirs(projectName) { const tmpDirPath = await generateJsdoc._createTmpDir(projectName); @@ -118,7 +138,7 @@ async function createTmpDir(projectName) { * Write resources from workspace matching the given pattern to the given fs destination * * @private - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {string} parameters.pattern Pattern to match resources in workspace against * @param {string} parameters.targetPath Path to write the resources to @@ -146,7 +166,7 @@ async function writeResourcesToDir({workspace, pattern, targetPath}) { * Write api.json files of dependencies to given target path in a flat structure * * @private - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files * @param {string} parameters.targetPath Path to write the resources to * @returns {Promise} Promise resolving with number of resources written to given directory diff --git a/lib/tasks/replaceCopyright.js b/lib/tasks/replaceCopyright.js index d97d452bc..0dc2fd853 100644 --- a/lib/tasks/replaceCopyright.js +++ b/lib/tasks/replaceCopyright.js @@ -15,22 +15,22 @@ const stringReplacer = require("../processors/stringReplacer"); * * @public * @alias module:@ui5/builder.tasks.replaceCopyright - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.copyright Replacement copyright * @param {string} parameters.options.pattern Pattern to locate the files to be processed * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, options}) { - if (!options.copyright) { +module.exports = function({workspace, options: {copyright, pattern}}) { + if (!copyright) { return Promise.resolve(); } // Replace optional placeholder ${currentYear} with the current year - const copyright = options.copyright.replace(/(?:\$\{currentYear\})/, new Date().getFullYear()); + copyright = copyright.replace(/(?:\$\{currentYear\})/, new Date().getFullYear()); - return workspace.byGlob(options.pattern) + return workspace.byGlob(pattern) .then((processedResources) => { return stringReplacer({ resources: processedResources, diff --git a/lib/tasks/replaceVersion.js b/lib/tasks/replaceVersion.js index add78b23b..5bf16e697 100644 --- a/lib/tasks/replaceVersion.js +++ b/lib/tasks/replaceVersion.js @@ -5,21 +5,21 @@ const stringReplacer = require("../processors/stringReplacer"); * * @public * @alias module:@ui5/builder.tasks.replaceVersion - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.pattern Pattern to locate the files to be processed * @param {string} parameters.options.version Replacement version * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, options}) { - return workspace.byGlob(options.pattern) +module.exports = function({workspace, options: {pattern, version}}) { + return workspace.byGlob(pattern) .then((allResources) => { return stringReplacer({ resources: allResources, options: { pattern: "${version}", - replacement: options.version + replacement: version } }); }) diff --git a/lib/tasks/taskRepository.js b/lib/tasks/taskRepository.js index b45560f48..aa45af249 100644 --- a/lib/tasks/taskRepository.js +++ b/lib/tasks/taskRepository.js @@ -1,47 +1,59 @@ -const tasks = { - replaceCopyright: require("./replaceCopyright"), - replaceVersion: require("./replaceVersion"), - createDebugFiles: require("./createDebugFiles"), - escapeNonAsciiCharacters: require("./escapeNonAsciiCharacters"), - executeJsdocSdkTransformation: require("./jsdoc/executeJsdocSdkTransformation"), - generateApiIndex: require("./jsdoc/generateApiIndex"), - generateJsdoc: require("./jsdoc/generateJsdoc"), - uglify: require("./uglify"), - buildThemes: require("./buildThemes"), - transformBootstrapHtml: require("./transformBootstrapHtml"), - generateLibraryManifest: require("./generateLibraryManifest"), - generateVersionInfo: require("./generateVersionInfo"), - generateManifestBundle: require("./bundlers/generateManifestBundle"), - generateFlexChangesBundle: require("./bundlers/generateFlexChangesBundle"), - generateComponentPreload: require("./bundlers/generateComponentPreload"), - generateStandaloneAppBundle: require("./bundlers/generateStandaloneAppBundle"), - generateBundle: require("./bundlers/generateBundle"), - generateLibraryPreload: require("./bundlers/generateLibraryPreload"), - generateCachebusterInfo: require("./generateCachebusterInfo") +const taskInfos = { + replaceCopyright: {path: "./replaceCopyright"}, + replaceVersion: {path: "./replaceVersion"}, + createDebugFiles: {path: "./createDebugFiles"}, + escapeNonAsciiCharacters: {path: "./escapeNonAsciiCharacters"}, + executeJsdocSdkTransformation: {path: "./jsdoc/executeJsdocSdkTransformation"}, + generateApiIndex: {path: "./jsdoc/generateApiIndex"}, + generateJsdoc: {path: "./jsdoc/generateJsdoc"}, + uglify: {path: "./uglify"}, + buildThemes: {path: "./buildThemes"}, + transformBootstrapHtml: {path: "./transformBootstrapHtml"}, + generateLibraryManifest: {path: "./generateLibraryManifest"}, + generateVersionInfo: {path: "./generateVersionInfo"}, + generateManifestBundle: {path: "./bundlers/generateManifestBundle"}, + generateFlexChangesBundle: {path: "./bundlers/generateFlexChangesBundle"}, + generateComponentPreload: {path: "./bundlers/generateComponentPreload"}, + generateResourcesJson: {path: "./generateResourcesJson"}, + generateStandaloneAppBundle: {path: "./bundlers/generateStandaloneAppBundle"}, + generateBundle: {path: "./bundlers/generateBundle"}, + generateLibraryPreload: {path: "./bundlers/generateLibraryPreload"}, + generateCachebusterInfo: {path: "./generateCachebusterInfo"} }; function getTask(taskName) { - const task = tasks[taskName]; + const taskInfo = taskInfos[taskName]; - if (!task) { + if (!taskInfo) { throw new Error(`taskRepository: Unknown Task ${taskName}`); } - return task; + try { + const task = require(taskInfo.path); + return { + task, + specVersion: taskInfo.specVersion + }; + } catch (err) { + throw new Error(`taskRepository: Failed to require task module for ${taskName}: ${err.message}`); + } } -function addTask(name, task) { - if (tasks[name]) { - throw new Error(`taskRepository: Task ${name} already registered`); +function addTask({name, specVersion, taskPath}) { + if (taskInfos[name]) { + throw new Error(`taskRepository: A task with the name ${name} has already been registered`); } - tasks[name] = task; + taskInfos[name] = { + path: taskPath, + specVersion + }; } -function getAllTasks() { - return tasks; +function getAllTaskNames() { + return Object.keys(taskInfos); } module.exports = { - getTask: getTask, - addTask: addTask, - getAllTasks: getAllTasks + getTask, + addTask, + getAllTaskNames }; diff --git a/lib/tasks/transformBootstrapHtml.js b/lib/tasks/transformBootstrapHtml.js index cef44ea9d..0477757eb 100644 --- a/lib/tasks/transformBootstrapHtml.js +++ b/lib/tasks/transformBootstrapHtml.js @@ -5,23 +5,23 @@ const bootstrapHtmlTransformer = require("../processors/bootstrapHtmlTransformer * Task for transforming the application bootstrap HTML file. * * @module builder/tasks/transformBootstrapHtml - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} parameters.options Options + * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @param {string} [parameters.options.namespace] Project namespace * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, options}) { +module.exports = async function({workspace, options: {projectName, namespace}}) { let indexPath; - if (options.namespace) { - indexPath = `/resources/${options.namespace}/index.html`; + if (namespace) { + indexPath = `/resources/${namespace}/index.html`; } else { indexPath = "/index.html"; } const resource = await workspace.byPath(indexPath); if (!resource) { - log.warn(`Skipping bootstrap transformation due to missing index.html in project "${options.projectName}".`); + log.warn(`Skipping bootstrap transformation due to missing index.html in project "${projectName}".`); return; } const processedResources = await bootstrapHtmlTransformer({ diff --git a/lib/tasks/uglify.js b/lib/tasks/uglify.js index 7bcf79114..60884fda1 100644 --- a/lib/tasks/uglify.js +++ b/lib/tasks/uglify.js @@ -5,17 +5,24 @@ const uglifyProcessor = require("../processors/uglifier"); * * @public * @alias module:@ui5/builder.tasks.uglify - * @param {Object} parameters Parameters + * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - * @param {Object} parameters.options Options + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil + * @param {object} parameters.options Options * @param {string} parameters.options.pattern Pattern to locate the files to be processed * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, options}) { - return workspace.byGlobSource(options.pattern) +module.exports = function({workspace, taskUtil, options: {pattern}}) { + return workspace.byGlobSource(pattern) .then((allResources) => { + let resources = allResources; + if (taskUtil) { + resources = allResources.filter((resource) => { + return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.IsBundle); + }); + } return uglifyProcessor({ - resources: allResources + resources }); }) .then((processedResources) => { diff --git a/lib/types/AbstractBuilder.js b/lib/types/AbstractBuilder.js index b7536c003..994123849 100644 --- a/lib/types/AbstractBuilder.js +++ b/lib/types/AbstractBuilder.js @@ -1,3 +1,13 @@ + +/** + * Resource collections + * + * @public + * @typedef module:@ui5/builder.BuilderResourceCollections + * @property {module:@ui5/fs.DuplexCollection} workspace Workspace Resource + * @property {module:@ui5/fs.ReaderCollection} dependencies Workspace Resource + */ + /** * Base class for the builder implementation of a project type * @@ -7,14 +17,13 @@ class AbstractBuilder { /** * Constructor * - * @param {Object} parameters - * @param {Object} parameters.resourceCollections Resource collections - * @param {module:@ui5/fs.DuplexCollection} parameters.resourceCollections.workspace Workspace Resource - * @param {ReaderCollection} parameters.resourceCollections.dependencies Workspace Resource - * @param {Object} parameters.project Project configuration + * @param {object} parameters + * @param {BuilderResourceCollections} parameters.resourceCollections Resource collections + * @param {object} parameters.project Project configuration * @param {GroupLogger} parameters.parentLogger Logger to use + * @param {object} parameters.taskUtil */ - constructor({resourceCollections, project, parentLogger, buildContext}) { + constructor({resourceCollections, project, parentLogger, taskUtil}) { if (new.target === AbstractBuilder) { throw new TypeError("Class 'AbstractBuilder' is abstract"); } @@ -26,8 +35,17 @@ class AbstractBuilder { this.tasks = {}; this.taskExecutionOrder = []; - this.addStandardTasks({resourceCollections, project, log: this.log, buildContext}); - this.addCustomTasks({resourceCollections, project, buildContext}); + this.addStandardTasks({ + resourceCollections, + project, + log: this.log, + taskUtil + }); + this.addCustomTasks({ + resourceCollections, + project, + taskUtil + }); } /** @@ -35,14 +53,13 @@ class AbstractBuilder { * * @abstract * @protected - * @param {Object} parameters - * @param {Object} parameters.resourceCollections Resource collections - * @param {module:@ui5/fs.DuplexCollection} parameters.resourceCollections.workspace Workspace Resource - * @param {ReaderCollection} parameters.resourceCollections.dependencies Workspace Resource - * @param {Object} parameters.project Project configuration - * @param {Object} parameters.log @ui5/logger logger instance + * @param {object} parameters + * @param {BuilderResourceCollections} parameters.resourceCollections Resource collections + * @param {object} parameters.taskUtil + * @param {object} parameters.project Project configuration + * @param {object} parameters.log @ui5/logger logger instance */ - addStandardTasks({resourceCollections, project, log, buildContext}) { + addStandardTasks({resourceCollections, project, log, taskUtil}) { throw new Error("Function 'addStandardTasks' is not implemented"); } @@ -50,13 +67,12 @@ class AbstractBuilder { * Adds custom tasks to execute * * @private - * @param {Object} parameters - * @param {Object} parameters.resourceCollections Resource collections - * @param {module:@ui5/fs.DuplexCollection} parameters.resourceCollections.workspace Workspace Resource - * @param {ReaderCollection} parameters.resourceCollections.dependencies Workspace Resource - * @param {Object} parameters.project Project configuration + * @param {object} parameters + * @param {BuilderResourceCollections} parameters.resourceCollections Resource collections + * @param {object} parameters.taskUtil + * @param {object} parameters.project Project configuration */ - addCustomTasks({resourceCollections, project, buildContext}) { + addCustomTasks({resourceCollections, project, taskUtil}) { const projectCustomTasks = project.builder && project.builder.customTasks; if (!projectCustomTasks || projectCustomTasks.length === 0) { return; // No custom tasks defined @@ -72,7 +88,8 @@ class AbstractBuilder { throw new Error(`Custom task definition ${taskDef.name} of project ${project.metadata.name} ` + `defines both "beforeTask" and "afterTask" parameters. Only one must be defined.`); } - if (!taskDef.beforeTask && !taskDef.afterTask) { + if (this.taskExecutionOrder.length && !taskDef.beforeTask && !taskDef.afterTask) { + // Iff there are tasks configured, beforeTask or afterTask must be given throw new Error(`Custom task definition ${taskDef.name} of project ${project.metadata.name} ` + `defines neither a "beforeTask" nor an "afterTask" parameter. One must be defined.`); } @@ -88,13 +105,16 @@ class AbstractBuilder { } } // Create custom task if not already done (task might be referenced multiple times, first one wins) - const task = taskRepository.getTask(taskDef.name); + const {specVersion, task} = taskRepository.getTask(taskDef.name); const execTask = function() { /* Custom Task Interface Parameters: {Object} parameters Parameters {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files - {module:@ui5/fs.AbstractReader} parameters.dependencies Reader or Collection to read dependency files + {module:@ui5/fs.AbstractReader} parameters.dependencies + Reader or Collection to read dependency files + {Object} parameters.taskUtil Specification Version dependent interface to a + [TaskUtil]{@link module:@ui5/builder.tasks.TaskUtil} instance {Object} parameters.options Options {string} parameters.options.projectName Project name {string} [parameters.options.projectNamespace] Project namespace if available @@ -102,7 +122,7 @@ class AbstractBuilder { Returns: {Promise} Promise resolving with undefined once data has been written */ - return task({ + const params = { workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, options: { @@ -110,22 +130,35 @@ class AbstractBuilder { projectNamespace: project.metadata.namespace, configuration: taskDef.configuration } - }); + }; + + const taskUtilInterface = taskUtil.getInterface(specVersion); + // Interface is undefined if specVersion does not support taskUtil + if (taskUtilInterface) { + params.taskUtil = taskUtilInterface; + } + return task(params); }; this.tasks[newTaskName] = execTask; - const refTaskName = taskDef.beforeTask || taskDef.afterTask; - let refTaskIdx = this.taskExecutionOrder.indexOf(refTaskName); - if (refTaskIdx === -1) { - throw new Error(`Could not find task ${refTaskName}, referenced by custom task ${newTaskName}, ` + - `to be scheduled for project ${project.metadata.name}`); - } - if (taskDef.afterTask) { - // Insert after index of referenced task - refTaskIdx++; + if (this.taskExecutionOrder.length) { + // There is at least one task configured. Use before- and afterTask to add the custom task + const refTaskName = taskDef.beforeTask || taskDef.afterTask; + let refTaskIdx = this.taskExecutionOrder.indexOf(refTaskName); + if (refTaskIdx === -1) { + throw new Error(`Could not find task ${refTaskName}, referenced by custom task ${newTaskName}, ` + + `to be scheduled for project ${project.metadata.name}`); + } + if (taskDef.afterTask) { + // Insert after index of referenced task + refTaskIdx++; + } + this.taskExecutionOrder.splice(refTaskIdx, 0, newTaskName); + } else { + // There is no task configured so far. Just add the custom task + this.taskExecutionOrder.push(newTaskName); } - this.taskExecutionOrder.splice(refTaskIdx, 0, newTaskName); } } @@ -149,6 +182,17 @@ class AbstractBuilder { this.taskExecutionOrder.push(taskName); } + /** + * Check whether a task is defined + * + * @private + * @param {string} taskName + * @returns {boolean} + */ + hasTask(taskName) { + return Object.prototype.hasOwnProperty.call(this.tasks, taskName); + } + /** * Takes a list of tasks which should be executed from the available task list of the current builder * @@ -156,13 +200,13 @@ class AbstractBuilder { * @returns {Promise} Returns promise chain with tasks */ build(tasksToRun) { - const allTasksCount = tasksToRun.filter((value) => this.tasks.hasOwnProperty(value)).length; + const allTasksCount = tasksToRun.filter((value) => this.hasTask(value)).length; this.taskLog.addWork(allTasksCount); let taskChain = Promise.resolve(); for (let i = 0; i < this.taskExecutionOrder.length; i++) { const taskName = this.taskExecutionOrder[i]; - if (this.tasks.hasOwnProperty(taskName) && tasksToRun.includes(taskName)) { + if (this.hasTask(taskName) && tasksToRun.includes(taskName)) { const taskFunction = this.tasks[taskName]; if (typeof taskFunction === "function") { diff --git a/lib/types/AbstractFormatter.js b/lib/types/AbstractFormatter.js index cc07d7d26..a842cf148 100644 --- a/lib/types/AbstractFormatter.js +++ b/lib/types/AbstractFormatter.js @@ -9,8 +9,8 @@ class AbstractFormatter { /** * Constructor * - * @param {Object} parameters - * @param {Object} parameters.project Project + * @param {object} parameters + * @param {object} parameters.project Project */ constructor({project}) { if (new.target === AbstractFormatter) { diff --git a/lib/types/AbstractUi5Formatter.js b/lib/types/AbstractUi5Formatter.js index cab0ce352..252f4e9a7 100644 --- a/lib/types/AbstractUi5Formatter.js +++ b/lib/types/AbstractUi5Formatter.js @@ -15,8 +15,8 @@ class AbstractUi5Formatter extends AbstractFormatter { /** * Constructor * - * @param {Object} parameters - * @param {Object} parameters.project Project + * @param {object} parameters + * @param {object} parameters.project Project */ constructor(parameters) { super(parameters); @@ -70,7 +70,7 @@ class AbstractUi5Formatter extends AbstractFormatter { /** * Reads the projects pom.xml file * - * @returns {Promise} Resolves with a JSON representation of the content + * @returns {Promise} Resolves with a JSON representation of the content */ async getPom() { if (this._pPom) { diff --git a/lib/types/application/ApplicationBuilder.js b/lib/types/application/ApplicationBuilder.js index 67043e786..5fe22513e 100644 --- a/lib/types/application/ApplicationBuilder.js +++ b/lib/types/application/ApplicationBuilder.js @@ -1,37 +1,20 @@ const AbstractBuilder = require("../AbstractBuilder"); - -const tasks = { // can't require index.js due to circular dependency - generateComponentPreload: require("../../tasks/bundlers/generateComponentPreload"), - generateFlexChangesBundle: require("../../tasks/bundlers/generateFlexChangesBundle"), - generateLibraryPreload: require("../../tasks/bundlers/generateLibraryPreload"), - generateManifestBundle: require("../../tasks/bundlers/generateManifestBundle"), - generateStandaloneAppBundle: require("../../tasks/bundlers/generateStandaloneAppBundle"), - generateBundle: require("../../tasks/bundlers/generateBundle"), - generateCachebusterInfo: require("../../tasks/generateCachebusterInfo"), - escapeNonAsciiCharacters: require("../../tasks/escapeNonAsciiCharacters"), - buildThemes: require("../../tasks/buildThemes"), - createDebugFiles: require("../../tasks/createDebugFiles"), - generateVersionInfo: require("../../tasks/generateVersionInfo"), - replaceCopyright: require("../../tasks/replaceCopyright"), - replaceVersion: require("../../tasks/replaceVersion"), - transformBootstrapHtml: require("../../tasks/transformBootstrapHtml"), - uglify: require("../../tasks/uglify"), - generateApiIndex: require("../../tasks/jsdoc/generateApiIndex") -}; +const {getTask} = require("../../tasks/taskRepository"); class ApplicationBuilder extends AbstractBuilder { - addStandardTasks({resourceCollections, project, log}) { + addStandardTasks({resourceCollections, project, log, taskUtil}) { if (!project.metadata.namespace) { + // TODO 3.0: Throw here log.info("Skipping some tasks due to missing application namespace information. If your project contains " + "a Component.js, you might be missing a manifest.json file. " + - "Also see: https://github.com/SAP/ui5-builder#application"); + "Also see: https://sap.github.io/ui5-tooling/pages/Builder/#application"); } - this.addTask("escapeNonAsciiCharacters", () => { - const propertiesFileSourceEncoding = project.resources - && project.resources.configuration - && project.resources.configuration.propertiesFileSourceEncoding; - return tasks.escapeNonAsciiCharacters({ + this.addTask("escapeNonAsciiCharacters", async () => { + const propertiesFileSourceEncoding = project.resources && + project.resources.configuration && + project.resources.configuration.propertiesFileSourceEncoding; + return getTask("escapeNonAsciiCharacters").task({ workspace: resourceCollections.workspace, options: { encoding: propertiesFileSourceEncoding, @@ -40,8 +23,8 @@ class ApplicationBuilder extends AbstractBuilder { }); }); - this.addTask("replaceCopyright", () => { - return tasks.replaceCopyright({ + this.addTask("replaceCopyright", async () => { + return getTask("replaceCopyright").task({ workspace: resourceCollections.workspace, options: { copyright: project.metadata.copyright, @@ -50,8 +33,8 @@ class ApplicationBuilder extends AbstractBuilder { }); }); - this.addTask("replaceVersion", () => { - return tasks.replaceVersion({ + this.addTask("replaceVersion", async () => { + return getTask("replaceVersion").task({ workspace: resourceCollections.workspace, options: { version: project.version, @@ -60,10 +43,11 @@ class ApplicationBuilder extends AbstractBuilder { }); }); - this.addTask("generateFlexChangesBundle", () => { - const generateFlexChangesBundle = tasks.generateFlexChangesBundle; + this.addTask("generateFlexChangesBundle", async () => { + const generateFlexChangesBundle = getTask("generateFlexChangesBundle").task; return generateFlexChangesBundle({ workspace: resourceCollections.workspace, + taskUtil, options: { namespace: project.metadata.namespace } @@ -71,8 +55,8 @@ class ApplicationBuilder extends AbstractBuilder { }); if (project.metadata.namespace) { - this.addTask("generateManifestBundle", () => { - const generateManifestBundle = tasks.generateManifestBundle; + this.addTask("generateManifestBundle", async () => { + const generateManifestBundle = getTask("generateManifestBundle").task; return generateManifestBundle({ workspace: resourceCollections.workspace, options: { @@ -86,9 +70,10 @@ class ApplicationBuilder extends AbstractBuilder { const componentPreload = project.builder && project.builder.componentPreload; if (componentPreload) { this.addTask("generateComponentPreload", async () => { - return tasks.generateComponentPreload({ + return getTask("generateComponentPreload").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, paths: componentPreload.paths, @@ -99,9 +84,10 @@ class ApplicationBuilder extends AbstractBuilder { } else if (project.metadata.namespace) { // Default component preload for application namespace this.addTask("generateComponentPreload", async () => { - return tasks.generateComponentPreload({ + return getTask("generateComponentPreload").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, namespaces: [project.metadata.namespace] @@ -110,10 +96,11 @@ class ApplicationBuilder extends AbstractBuilder { }); } - this.addTask("generateStandaloneAppBundle", () => { - return tasks.generateStandaloneAppBundle({ + this.addTask("generateStandaloneAppBundle", async () => { + return getTask("generateStandaloneAppBundle").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, namespace: project.metadata.namespace @@ -121,8 +108,8 @@ class ApplicationBuilder extends AbstractBuilder { }); }); - this.addTask("transformBootstrapHtml", () => { - return tasks.transformBootstrapHtml({ + this.addTask("transformBootstrapHtml", async () => { + return getTask("transformBootstrapHtml").task({ workspace: resourceCollections.workspace, options: { projectName: project.metadata.name, @@ -133,11 +120,12 @@ class ApplicationBuilder extends AbstractBuilder { const bundles = project.builder && project.builder.bundles; if (bundles) { - this.addTask("generateBundle", () => { + this.addTask("generateBundle", async () => { return Promise.all(bundles.map((bundle) => { - return tasks.generateBundle({ + return getTask("generateBundle").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, bundleDefinition: bundle.bundleDefinition, @@ -148,8 +136,8 @@ class ApplicationBuilder extends AbstractBuilder { }); } - this.addTask("createDebugFiles", () => { - const createDebugFiles = tasks.createDebugFiles; + this.addTask("createDebugFiles", async () => { + const createDebugFiles = getTask("createDebugFiles").task; return createDebugFiles({ workspace: resourceCollections.workspace, options: { @@ -158,44 +146,55 @@ class ApplicationBuilder extends AbstractBuilder { }); }); - this.addTask("uglify", () => { - const uglify = tasks.uglify; + this.addTask("uglify", async () => { + const uglify = getTask("uglify").task; return uglify({ workspace: resourceCollections.workspace, + taskUtil, options: { pattern: "/**/*.js" } }); }); - this.addTask("generateVersionInfo", () => { - return tasks.generateVersionInfo({ + this.addTask("generateVersionInfo", async () => { + return getTask("generateVersionInfo").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, options: { rootProject: project, - pattern: "/**/.library" + pattern: "/resources/**/.library" } }); }); if (project.metadata.namespace) { - this.addTask("generateCachebusterInfo", () => { - return tasks.generateCachebusterInfo({ + this.addTask("generateCachebusterInfo", async () => { + return getTask("generateCachebusterInfo").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, options: { namespace: project.metadata.namespace, - signatureType: project.builder - && project.builder.cachebuster - && project.builder.cachebuster.signatureType, + signatureType: project.builder && + project.builder.cachebuster && + project.builder.cachebuster.signatureType, } }); }); } - this.addTask("generateApiIndex", () => { - return tasks.generateApiIndex({ + this.addTask("generateApiIndex", async () => { + return getTask("generateApiIndex").task({ + workspace: resourceCollections.workspace, + dependencies: resourceCollections.dependencies, + options: { + projectName: project.metadata.name + } + }); + }); + + this.addTask("generateResourcesJson", () => { + return getTask("generateResourcesJson").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, options: { diff --git a/lib/types/application/ApplicationFormatter.js b/lib/types/application/ApplicationFormatter.js index 2a3fb0b3e..803f60997 100644 --- a/lib/types/application/ApplicationFormatter.js +++ b/lib/types/application/ApplicationFormatter.js @@ -7,6 +7,16 @@ const slash = require("slash"); const AbstractUi5Formatter = require("../AbstractUi5Formatter"); class ApplicationFormatter extends AbstractUi5Formatter { + /** + * Constructor + * + * @param {object} parameters + * @param {object} parameters.project Project + */ + constructor(parameters) { + super(parameters); + this._pManifests = {}; + } /** * Formats and validates the project * @@ -20,13 +30,7 @@ class ApplicationFormatter extends AbstractUi5Formatter { "/": project.resources.configuration.paths.webapp }; - try { - project.metadata.namespace = await this.getNamespace(); - } catch (err) { - // Catch error because namespace is optional - // TODO 2.0: Make namespace mandatory and just let the error throw - log.warn(err.message); - } + project.metadata.namespace = await this.getNamespace(); } /** @@ -46,6 +50,39 @@ class ApplicationFormatter extends AbstractUi5Formatter { return p.join(projectPath, this._project.resources.pathMappings["/"]); } + /** + * Determine application namespace either based on a project`s + * manifest.json or manifest.appdescr_variant (fallback if present) + * + * @returns {string} Namespace of the project + * @throws {Error} if namespace can not be determined + */ + async getNamespace() { + try { + return await this.getNamespaceFromManifestJson(); + } catch (manifestJsonError) { + if (manifestJsonError.code !== "ENOENT") { + throw manifestJsonError; + } + // No manifest.json present + // => attempt fallback to manifest.appdescr_variant (typical for App Variants) + try { + return await this.getNamespaceFromManifestAppDescVariant(); + } catch (appDescVarError) { + if (appDescVarError.code === "ENOENT") { + // Fallback not possible: No manifest.appdescr_variant present + // => Throw error indicating missing manifest.json + // (do not mention manifest.appdescr_variant since it is only + // relevant for the rather "uncommon" App Variants) + throw new Error( + `Could not find required manifest.json for project ` + + `${this._project.metadata.name}: ${manifestJsonError.message}`); + } + throw appDescVarError; + } + } + } + /** * Determine application namespace by checking manifest.json. * Any maven placeholders are resolved from the projects pom.xml @@ -53,15 +90,15 @@ class ApplicationFormatter extends AbstractUi5Formatter { * @returns {string} Namespace of the project * @throws {Error} if namespace can not be determined */ - async getNamespace() { - const {content: manifest} = await this.getManifest(); + async getNamespaceFromManifestJson() { + const {content: manifest} = await this.getJson("manifest.json"); let appId; // check for a proper sap.app/id in manifest.json to determine namespace if (manifest["sap.app"] && manifest["sap.app"].id) { - appId = manifest["sap.app"] && manifest["sap.app"].id; + appId = manifest["sap.app"].id; } else { throw new Error( - `No "sap.app" ID configuration found in manifest.json of project ${this._project.metadata.name}`); + `No sap.app/id configuration found in manifest.json of project ${this._project.metadata.name}`); } if (this.hasMavenPlaceholder(appId)) { @@ -73,22 +110,47 @@ class ApplicationFormatter extends AbstractUi5Formatter { } } const namespace = appId.replace(/\./g, "/"); - log.verbose(`Namespace of project ${this._project.metadata.name} is ${namespace}`); + log.verbose( + `Namespace of project ${this._project.metadata.name} is ${namespace} (from manifest.appdescr_variant)`); + return namespace; + } + + /** + * Determine application namespace by checking manifest.appdescr_variant. + * + * @returns {string} Namespace of the project + * @throws {Error} if namespace can not be determined + */ + async getNamespaceFromManifestAppDescVariant() { + const {content: manifest} = await this.getJson("manifest.appdescr_variant"); + let appId; + // check for the id property in manifest.appdescr_variant to determine namespace + if (manifest && manifest.id) { + appId = manifest.id; + } else { + throw new Error( + `No "id" property found in manifest.appdescr_variant of project ${this._project.metadata.name}`); + } + + const namespace = appId.replace(/\./g, "/"); + log.verbose( + `Namespace of project ${this._project.metadata.name} is ${namespace} (from manifest.appdescr_variant)`); return namespace; } /** - * Reads the projects manifest.json + * Reads and parses a JSON file with the provided name from the projects source directory * - * @returns {Promise} resolves with an object containing the content (as JSON) and - * fsPath (as string) of the manifest.json file + * @param {string} fileName Name of the JSON file to read. Typically "manifest.json" or "manifest.appdescr_variant" + * @returns {Promise} resolves with an object containing the content (as JSON) and + * fsPath (as string) of the requested file */ - async getManifest() { - if (this._pManifest) { - return this._pManifest; + async getJson(fileName) { + if (this._pManifests[fileName]) { + return this._pManifests[fileName]; } - const fsPath = path.join(this.getSourceBasePath(), "manifest.json"); - return this._pManifest = readFile(fsPath) + const fsPath = path.join(this.getSourceBasePath(), fileName); + return this._pManifests[fileName] = readFile(fsPath) .then((content) => { return { content: JSON.parse(content), @@ -96,8 +158,12 @@ class ApplicationFormatter extends AbstractUi5Formatter { }; }) .catch((err) => { + if (err.code === "ENOENT") { + throw err; + } throw new Error( - `Failed to read manifest.json for project ${this._project.metadata.name}: ${err.message}`); + `Failed to read ${fileName} for project ` + + `${this._project.metadata.name}: ${err.message}`); }); } @@ -133,13 +199,19 @@ class ApplicationFormatter extends AbstractUi5Formatter { project.resources.configuration.paths.webapp = "webapp"; } - // default encoding to "ISO-8859-1" if not specified if (!project.resources.configuration.propertiesFileSourceEncoding) { - project.resources.configuration.propertiesFileSourceEncoding = "ISO-8859-1"; + if (["0.1", "1.0", "1.1"].includes(project.specVersion)) { + // default encoding to "ISO-8859-1" for old specVersions + project.resources.configuration.propertiesFileSourceEncoding = "ISO-8859-1"; + } else { + // default encoding to "UTF-8" for all projects starting with specVersion 2.0 + project.resources.configuration.propertiesFileSourceEncoding = "UTF-8"; + } } if (!["ISO-8859-1", "UTF-8"].includes(project.resources.configuration.propertiesFileSourceEncoding)) { - throw new Error(`Invalid properties file encoding specified for project ${project.id}: ` + - `encoding provided: ${project.resources.configuration.propertiesFileSourceEncoding}. Must be either "ISO-8859-1" or "UTF-8".`); + throw new Error(`Invalid properties file encoding specified for project ${project.id}. ` + + `Encoding provided: ${project.resources.configuration.propertiesFileSourceEncoding}. ` + + `Must be either "ISO-8859-1" or "UTF-8".`); } const absolutePath = path.join(project.path, project.resources.configuration.paths.webapp); diff --git a/lib/types/application/applicationType.js b/lib/types/application/applicationType.js index 78bb461fb..8f27d5ca9 100644 --- a/lib/types/application/applicationType.js +++ b/lib/types/application/applicationType.js @@ -5,8 +5,8 @@ module.exports = { format: function(project) { return new ApplicationFormatter({project}).format(); }, - build: function({resourceCollections, tasks, project, parentLogger, buildContext}) { - return new ApplicationBuilder({resourceCollections, project, parentLogger, buildContext}).build(tasks); + build: function({resourceCollections, tasks, project, parentLogger, taskUtil}) { + return new ApplicationBuilder({resourceCollections, project, parentLogger, taskUtil}).build(tasks); }, // Export type classes for extensibility diff --git a/lib/types/library/LibraryBuilder.js b/lib/types/library/LibraryBuilder.js index b1125b794..f5c977d63 100644 --- a/lib/types/library/LibraryBuilder.js +++ b/lib/types/library/LibraryBuilder.js @@ -1,36 +1,20 @@ const AbstractBuilder = require("../AbstractBuilder"); -const tasks = { // can't require index.js due to circular dependency - generateComponentPreload: require("../../tasks/bundlers/generateComponentPreload"), - generateFlexChangesBundle: require("../../tasks/bundlers/generateFlexChangesBundle"), - generateBundle: require("../../tasks/bundlers/generateBundle"), - generateLibraryPreload: require("../../tasks/bundlers/generateLibraryPreload"), - generateManifestBundle: require("../../tasks/bundlers/generateManifestBundle"), - generateStandaloneAppBundle: require("../../tasks/bundlers/generateStandaloneAppBundle"), - escapeNonAsciiCharacters: require("../../tasks/escapeNonAsciiCharacters"), - buildThemes: require("../../tasks/buildThemes"), - createDebugFiles: require("../../tasks/createDebugFiles"), - generateJsdoc: require("../../tasks/jsdoc/generateJsdoc"), - executeJsdocSdkTransformation: require("../../tasks/jsdoc/executeJsdocSdkTransformation"), - generateLibraryManifest: require("../../tasks/generateLibraryManifest"), - generateVersionInfo: require("../../tasks/generateVersionInfo"), - replaceCopyright: require("../../tasks/replaceCopyright"), - replaceVersion: require("../../tasks/replaceVersion"), - uglify: require("../../tasks/uglify") -}; +const {getTask} = require("../../tasks/taskRepository"); class LibraryBuilder extends AbstractBuilder { - addStandardTasks({resourceCollections, project, log, buildContext}) { + addStandardTasks({resourceCollections, project, log, taskUtil}) { if (!project.metadata.namespace) { + // TODO 3.0: Throw here log.info("Skipping some tasks due to missing library namespace information. Your project " + "might be missing a manifest.json or .library file. " + - "Also see: https://github.com/SAP/ui5-builder#library"); + "Also see: https://sap.github.io/ui5-tooling/pages/Builder/#library"); } - this.addTask("escapeNonAsciiCharacters", () => { - const propertiesFileSourceEncoding = project.resources - && project.resources.configuration - && project.resources.configuration.propertiesFileSourceEncoding; - return tasks.escapeNonAsciiCharacters({ + this.addTask("escapeNonAsciiCharacters", async () => { + const propertiesFileSourceEncoding = project.resources && + project.resources.configuration && + project.resources.configuration.propertiesFileSourceEncoding; + return getTask("escapeNonAsciiCharacters").task({ workspace: resourceCollections.workspace, options: { encoding: propertiesFileSourceEncoding, @@ -39,32 +23,28 @@ class LibraryBuilder extends AbstractBuilder { }); }); - this.addTask("replaceCopyright", () => { - const replaceCopyright = tasks.replaceCopyright; - return replaceCopyright({ + this.addTask("replaceCopyright", async () => { + return getTask("replaceCopyright").task({ workspace: resourceCollections.workspace, options: { copyright: project.metadata.copyright, - pattern: "/resources/**/*.{js,json,library}" + pattern: "/resources/**/*.{js,library,less,theme}" } }); }); - this.addTask("replaceVersion", () => { - const replaceVersion = tasks.replaceVersion; - return replaceVersion({ + this.addTask("replaceVersion", async () => { + return getTask("replaceVersion").task({ workspace: resourceCollections.workspace, options: { version: project.version, - pattern: "/resources/**/*.{js,json,library}" + pattern: "/resources/**/*.{js,json,library,less,theme}" } }); }); if (project.metadata.namespace) { - this.addTask("generateJsdoc", () => { - const generateJsdoc = tasks.generateJsdoc; - + this.addTask("generateJsdoc", async () => { const patterns = ["/resources/**/*.js"]; // Add excludes if (project.builder && project.builder.jsdoc && project.builder.jsdoc.excludes) { @@ -75,10 +55,10 @@ class LibraryBuilder extends AbstractBuilder { patterns.push(...excludes); } - return generateJsdoc({ - buildContext, + return getTask("generateJsdoc").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, namespace: project.metadata.namespace, @@ -88,10 +68,8 @@ class LibraryBuilder extends AbstractBuilder { }); }); - this.addTask("executeJsdocSdkTransformation", () => { - const executeJsdocSdkTransformation = tasks.executeJsdocSdkTransformation; - - return executeJsdocSdkTransformation({ + this.addTask("executeJsdocSdkTransformation", async () => { + return getTask("executeJsdocSdkTransformation").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, options: { @@ -104,12 +82,11 @@ class LibraryBuilder extends AbstractBuilder { const componentPreload = project.builder && project.builder.componentPreload; if (componentPreload) { - const generateComponentPreload = tasks.generateComponentPreload; - - this.addTask("generateComponentPreload", () => { - return generateComponentPreload({ + this.addTask("generateComponentPreload", async () => { + return getTask("generateComponentPreload").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, paths: componentPreload.paths, @@ -119,11 +96,11 @@ class LibraryBuilder extends AbstractBuilder { }); } - this.addTask("generateLibraryManifest", () => { - const generateLibraryManifest = tasks.generateLibraryManifest; - return generateLibraryManifest({ + this.addTask("generateLibraryManifest", async () => { + return getTask("generateLibraryManifest").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name } @@ -132,9 +109,8 @@ class LibraryBuilder extends AbstractBuilder { if (project.metadata.namespace) { - this.addTask("generateManifestBundle", () => { - const generateManifestBundle = tasks.generateManifestBundle; - return generateManifestBundle({ + this.addTask("generateManifestBundle", async () => { + return getTask("generateManifestBundle").task({ workspace: resourceCollections.workspace, options: { projectName: project.metadata.name, @@ -144,11 +120,11 @@ class LibraryBuilder extends AbstractBuilder { }); } - this.addTask("generateLibraryPreload", () => { - const generateLibraryPreload = tasks.generateLibraryPreload; - return generateLibraryPreload({ + this.addTask("generateLibraryPreload", async () => { + return getTask("generateLibraryPreload").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name } @@ -157,12 +133,13 @@ class LibraryBuilder extends AbstractBuilder { const bundles = project.builder && project.builder.bundles; if (bundles) { - this.addTask("generateBundle", () => { + this.addTask("generateBundle", async () => { return bundles.reduce(function(sequence, bundle) { return sequence.then(function() { - return tasks.generateBundle({ + return getTask("generateBundle").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name, bundleDefinition: bundle.bundleDefinition, @@ -174,22 +151,21 @@ class LibraryBuilder extends AbstractBuilder { }); } - this.addTask("buildThemes", () => { - const buildThemes = tasks.buildThemes; - return buildThemes({ + this.addTask("buildThemes", async () => { + return getTask("buildThemes").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, options: { projectName: project.metadata.name, - librariesPattern: "/resources/**/*.library", + librariesPattern: !taskUtil.isRootProject() ? "/resources/**/*.library" : undefined, + themesPattern: !taskUtil.isRootProject() ? "/resources/sap/ui/core/themes/*" : undefined, inputPattern: "/resources/**/themes/*/library.source.less" } }); }); - this.addTask("createDebugFiles", () => { - const createDebugFiles = tasks.createDebugFiles; - return createDebugFiles({ + this.addTask("createDebugFiles", async () => { + return getTask("createDebugFiles").task({ workspace: resourceCollections.workspace, options: { pattern: "/resources/**/*.js" @@ -197,15 +173,25 @@ class LibraryBuilder extends AbstractBuilder { }); }); - this.addTask("uglify", () => { - const uglify = tasks.uglify; - return uglify({ + this.addTask("uglify", async () => { + return getTask("uglify").task({ workspace: resourceCollections.workspace, + taskUtil, options: { pattern: "/resources/**/*.js" } }); }); + + this.addTask("generateResourcesJson", () => { + return getTask("generateResourcesJson").task({ + workspace: resourceCollections.workspace, + dependencies: resourceCollections.dependencies, + options: { + projectName: project.metadata.name + } + }); + }); } } diff --git a/lib/types/library/LibraryFormatter.js b/lib/types/library/LibraryFormatter.js index 7339d7184..d593bcaca 100644 --- a/lib/types/library/LibraryFormatter.js +++ b/lib/types/library/LibraryFormatter.js @@ -7,11 +7,12 @@ const glob = require("globby"); const slash = require("slash"); const AbstractUi5Formatter = require("../AbstractUi5Formatter"); +const SAP_THEMES_NS_EXEMPTIONS = ["themelib_sap_fiori_3", "themelib_sap_bluecrystal", "themelib_sap_belize"]; class LibraryFormatter extends AbstractUi5Formatter { /** * Formats and validates the project - * + * * @returns {Promise} */ async format() { @@ -27,16 +28,23 @@ class LibraryFormatter extends AbstractUi5Formatter { // Directory 'test' is somewhat optional for libraries project.resources.pathMappings["/test-resources/"] = project.resources.configuration.paths.test; } else { - log.verbose(`Ignoring 'test' directory for project ${project.metadata.name}.` + + log.verbose(`Ignoring 'test' directory for project ${project.metadata.name}. ` + "Either no setting was provided or the path not found."); } try { project.metadata.namespace = await this.getNamespace(); } catch (err) { - // Catch error because namespace is optional - // TODO 2.0: Make namespace mandatory and just let the error throw - log.warn(err.message); + if (SAP_THEMES_NS_EXEMPTIONS.includes(this._project.metadata.name)) { + // Exceptional handling for SAP theme libraries which used to be of type "library" + // (today they use "theme-library"). + // To allow use of OpenUI5 theme libraries in versions lower than 1.75 we must ignore + // namespace detection errors. + log.verbose(`Ignoring failed namespace detection for exempted SAP theme library ` + + `${this._project.metadata.name}: ${err.message}`); + } else { + throw err; + } } try { @@ -73,50 +81,83 @@ class LibraryFormatter extends AbstractUi5Formatter { * @throws {Error} if namespace can not be determined */ async getNamespace() { - let libraryId; + // Trigger both reads asynchronously + const [{ + namespace: manifestNs, + fsPath: manifestPath + }, { + namespace: dotLibraryNs, + fsPath: dotLibraryPath + }] = await Promise.all([ + this.getNamespaceFromManifest(), + this.getNamespaceFromDotLibrary() + ]); + + let libraryNs; let fsNamespacePath; - try { - const {content: manifest, fsPath} = await this.getManifest(); - // check for a proper sap.app/id in manifest.json to determine namespace - if (manifest["sap.app"] && manifest["sap.app"].id) { - log.verbose(`Found namespace information for project ${this._project.metadata.name} in ` + - `manifest.json`); - libraryId = manifest["sap.app"] && manifest["sap.app"].id; - fsNamespacePath = path.dirname(fsPath); - } else { - log.verbose( - `No "sap.app" ID configuration found in manifest.json of project ${this._project.metadata.name}`); - } - } catch (err) { - log.verbose(`Namespace resolution from manifest.json failed for project ` + - `${this._project.metadata.name}: ${err.message}`); - log.verbose(`Falling back to .library file...`); - } + if (manifestNs && dotLibraryNs) { + // Both files present + // => check whether they are on the same level + const manifestDepth = manifestPath.split(path.sep).length; + const dotLibraryDepth = dotLibraryPath.split(path.sep).length; - if (!libraryId) { - try { - const {content: dotLibrary, fsPath} = await this.getDotLibrary(); - if (dotLibrary && dotLibrary.library && dotLibrary.library.name) { - log.verbose(`Found namespace information for project ${this._project.metadata.name} in ` + - `.library file`); - libraryId = dotLibrary.library.name; - fsNamespacePath = path.dirname(fsPath); - } else { - throw new Error( - `No library name found in .library of project ${this._project.metadata.name}`); + if (manifestDepth < dotLibraryDepth) { + // We see the .library file as the "leading" file of a library + // Therefore, a manifest.json on a higher level is something we do not except + throw new Error(`Failed to detect namespace for project ${this._project.metadata.name}: ` + + `Found a manifest.json on a higher directory level than the .library file. ` + + `It should be on the same or a lower level. ` + + `Note that a manifest.json on a lower level will be ignored.\n` + + ` manifest.json path: ${manifestPath}\n` + + ` is higher than\n` + + ` .library path: ${dotLibraryPath}`); + } + if (manifestDepth === dotLibraryDepth) { + if (path.dirname(manifestPath) !== path.dirname(dotLibraryPath)) { + // This just should not happen in your project + throw new Error(`Failed to detect namespace for project ${this._project.metadata.name}: ` + + `Found a manifest.json on the same directory level but in a different directory ` + + `than the .library file. They should be in the same directory.\n` + + ` manifest.json path: ${manifestPath}\n` + + ` is different to\n` + + ` .library path: ${dotLibraryPath}`); } - } catch (err) { - log.verbose(`Namespace resolution from .library failed for project ` + - `${this._project.metadata.name}: ${err.message}`); - log.verbose("Falling back to library.js file path..."); + // Typical scenario if both files are present + log.verbose(`Found a manifest.json and a .library file on the same level for ` + + `project ${this._project.metadata.name}.`); + log.verbose(`Resolving namespace of project ${this._project.metadata.name} from manifest.json...`); + libraryNs = manifestNs; + fsNamespacePath = path.dirname(manifestPath); + } else { + // Typical scenario: Some nested component has a manifest.json but the library itself only + // features a .library. => Ignore the manifest.json + log.verbose(`Ignoring manifest.json found on a lower level than the .library file of ` + + `project ${this._project.metadata.name}.`); + log.verbose(`Resolving namespace of project ${this._project.metadata.name} from .library...`); + libraryNs = dotLibraryNs; + fsNamespacePath = path.dirname(dotLibraryPath); } + } else if (manifestNs) { + // Only manifest available + log.verbose(`Resolving namespace of project ${this._project.metadata.name} from manifest.json...`); + libraryNs = manifestNs; + fsNamespacePath = path.dirname(manifestPath); + } else if (dotLibraryNs) { + // Only .library available + log.verbose(`Resolving namespace of project ${this._project.metadata.name} from .library...`); + libraryNs = dotLibraryNs; + fsNamespacePath = path.dirname(dotLibraryPath); + } else { + log.verbose(`Failed to resolve namespace of project ${this._project.metadata.name} from manifest.json ` + + `or .library file. Falling back to library.js file path...`); } let namespace; - if (libraryId) { - if (this.hasMavenPlaceholder(libraryId)) { + if (libraryNs) { + // Maven placeholders can only exist in manifest.json or .library configuration + if (this.hasMavenPlaceholder(libraryNs)) { try { - libraryId = await this.resolveMavenPlaceholder(libraryId); + libraryNs = await this.resolveMavenPlaceholder(libraryNs); } catch (err) { throw new Error( `Failed to resolve namespace maven placeholder of project ` + @@ -124,7 +165,7 @@ class LibraryFormatter extends AbstractUi5Formatter { } } - namespace = libraryId.replace(/\./g, "/"); + namespace = libraryNs.replace(/\./g, "/"); const namespacePath = this.getNamespaceFromFsPath(fsNamespacePath); if (namespacePath !== namespace) { @@ -157,6 +198,53 @@ class LibraryFormatter extends AbstractUi5Formatter { return namespace; } + async getNamespaceFromManifest() { + try { + const {content: manifest, fsPath} = await this.getManifest(); + // check for a proper sap.app/id in manifest.json to determine namespace + if (manifest["sap.app"] && manifest["sap.app"].id) { + const namespace = manifest["sap.app"].id; + log.verbose(`Found namespace ${namespace} in manifest.json of project ${this._project.metadata.name} ` + + `at ${fsPath}`); + return { + namespace, + fsPath + }; + } else { + log.verbose( + `No sap.app/id configuration found in manifest.json of project ${this._project.metadata.name} ` + + `at ${fsPath}`); + } + } catch (err) { + log.verbose(`Namespace resolution from manifest.json failed for project ` + + `${this._project.metadata.name}: ${err.message}`); + } + return {}; + } + + async getNamespaceFromDotLibrary() { + try { + const {content: dotLibrary, fsPath} = await this.getDotLibrary(); + if (dotLibrary && dotLibrary.library && dotLibrary.library.name) { + const namespace = dotLibrary.library.name; + log.verbose(`Found namespace ${namespace} in .library file of project ${this._project.metadata.name} ` + + `at ${fsPath}`); + return { + namespace, + fsPath + }; + } else { + throw new Error( + `No library name found in .library of project ${this._project.metadata.name} ` + + `at ${fsPath}`); + } + } catch (err) { + log.verbose(`Namespace resolution from .library failed for project ` + + `${this._project.metadata.name}: ${err.message}`); + } + return {}; + } + getNamespaceFromFsPath(fsPath) { // Transform path to POSIX and remove any trailing slashes const posixFsPath = slash(fsPath).replace(/\/$/, ""); @@ -206,7 +294,7 @@ class LibraryFormatter extends AbstractUi5Formatter { /** * Reads the projects manifest.json * - * @returns {Promise} resolves with an object containing the content (as JSON) and + * @returns {Promise} resolves with an object containing the content (as JSON) and * fsPath (as string) of the manifest.json file */ async getManifest() { @@ -242,7 +330,7 @@ class LibraryFormatter extends AbstractUi5Formatter { /** * Reads the .library file * - * @returns {Promise} resolves with an object containing the content (as JSON) and + * @returns {Promise} resolves with an object containing the content (as JSON) and * fsPath (as string) of the .library file */ async getDotLibrary() { @@ -340,13 +428,19 @@ class LibraryFormatter extends AbstractUi5Formatter { project.resources.configuration.paths.test = "test"; } - // default encoding to "ISO-8859-1" if not specified if (!project.resources.configuration.propertiesFileSourceEncoding) { - project.resources.configuration.propertiesFileSourceEncoding = "ISO-8859-1"; + if (["0.1", "1.0", "1.1"].includes(project.specVersion)) { + // default encoding to "ISO-8859-1" for old specVersions + project.resources.configuration.propertiesFileSourceEncoding = "ISO-8859-1"; + } else { + // default encoding to "UTF-8" for all projects starting with specVersion 2.0 + project.resources.configuration.propertiesFileSourceEncoding = "UTF-8"; + } } if (!["ISO-8859-1", "UTF-8"].includes(project.resources.configuration.propertiesFileSourceEncoding)) { - throw new Error(`Invalid properties file encoding specified for project ${project.id}: ` + - `encoding provided: ${project.resources.configuration.propertiesFileSourceEncoding}. Must be either "ISO-8859-1" or "UTF-8".`); + throw new Error(`Invalid properties file encoding specified for project ${project.id}. ` + + `Encoding provided: ${project.resources.configuration.propertiesFileSourceEncoding}. ` + + `Must be either "ISO-8859-1" or "UTF-8".`); } const absoluteSrcPath = path.join(project.path, project.resources.configuration.paths.src); @@ -361,7 +455,7 @@ class LibraryFormatter extends AbstractUi5Formatter { this.dirExists(absoluteTestPath).then(function(bExists) { if (!bExists) { log.verbose(`Could not find (optional) test directory of project ${project.id}: ` + - `${absoluteSrcPath}`); + `${absoluteTestPath}`); // Current signal to following consumers that "test" is not available is null project.resources.configuration.paths.test = null; } diff --git a/lib/types/library/libraryType.js b/lib/types/library/libraryType.js index fa582b1ea..2a9576645 100644 --- a/lib/types/library/libraryType.js +++ b/lib/types/library/libraryType.js @@ -5,8 +5,8 @@ module.exports = { format: function(project) { return new LibraryFormatter({project}).format(); }, - build: function({resourceCollections, tasks, project, parentLogger, buildContext}) { - return new LibraryBuilder({resourceCollections, project, parentLogger, buildContext}).build(tasks); + build: function({resourceCollections, tasks, project, parentLogger, taskUtil}) { + return new LibraryBuilder({resourceCollections, project, parentLogger, taskUtil}).build(tasks); }, // Export type classes for extensibility diff --git a/lib/types/module/ModuleBuilder.js b/lib/types/module/ModuleBuilder.js index e6a2bdb83..52ca9a677 100644 --- a/lib/types/module/ModuleBuilder.js +++ b/lib/types/module/ModuleBuilder.js @@ -1,10 +1,6 @@ const AbstractBuilder = require("../AbstractBuilder"); class ModuleBuilder extends AbstractBuilder { - constructor({resourceCollections, project, parentLogger}) { - super({resourceCollections, project, parentLogger}); - } - addStandardTasks() {/* nothing to do*/} } diff --git a/lib/types/module/ModuleFormatter.js b/lib/types/module/ModuleFormatter.js index 697a3e1f0..d5ad4eb83 100644 --- a/lib/types/module/ModuleFormatter.js +++ b/lib/types/module/ModuleFormatter.js @@ -37,16 +37,14 @@ class ModuleFormatter extends AbstractFormatter { } const paths = project.resources.configuration.paths; const dirChecks =[]; - for (const virPath in paths) { - if (paths.hasOwnProperty(virPath)) { - const absolutePath = path.join(project.path, paths[virPath]); - dirChecks.push(this.dirExists(absolutePath).then((bExists) => { - if (!bExists) { - throw new Error(`Could not find "${virPath}" directory of project ${project.id} at ` + + for (const virPath of Object.keys(paths)) { + const absolutePath = path.join(project.path, paths[virPath]); + dirChecks.push(this.dirExists(absolutePath).then((bExists) => { + if (!bExists) { + throw new Error(`Could not find "${virPath}" directory of project ${project.id} at ` + `${absolutePath}`); - } - })); - } + } + })); } return Promise.all(dirChecks); }); diff --git a/lib/types/module/moduleType.js b/lib/types/module/moduleType.js index 663ade150..83b204cc4 100644 --- a/lib/types/module/moduleType.js +++ b/lib/types/module/moduleType.js @@ -5,8 +5,8 @@ module.exports = { format: function(project) { return new ModuleFormatter({project}).format(); }, - build: function({resourceCollections, tasks, project, parentLogger}) { - return new ModuleBuilder({resourceCollections, project, parentLogger}).build(tasks); + build: function({resourceCollections, tasks, project, parentLogger, taskUtil}) { + return new ModuleBuilder({resourceCollections, project, parentLogger, taskUtil}).build(tasks); }, // Export type classes for extensibility diff --git a/lib/types/themeLibrary/ThemeLibraryBuilder.js b/lib/types/themeLibrary/ThemeLibraryBuilder.js new file mode 100644 index 000000000..b1b8799a5 --- /dev/null +++ b/lib/types/themeLibrary/ThemeLibraryBuilder.js @@ -0,0 +1,51 @@ +const AbstractBuilder = require("../AbstractBuilder"); +const {getTask} = require("../../tasks/taskRepository"); + +class ThemeLibraryBuilder extends AbstractBuilder { + addStandardTasks({resourceCollections, project, log, taskUtil}) { + this.addTask("replaceCopyright", async () => { + return getTask("replaceCopyright").task({ + workspace: resourceCollections.workspace, + options: { + copyright: project.metadata.copyright, + pattern: "/resources/**/*.{less,theme}" + } + }); + }); + + this.addTask("replaceVersion", async () => { + return getTask("replaceVersion").task({ + workspace: resourceCollections.workspace, + options: { + version: project.version, + pattern: "/resources/**/*.{less,theme}" + } + }); + }); + + this.addTask("buildThemes", async () => { + return getTask("buildThemes").task({ + workspace: resourceCollections.workspace, + dependencies: resourceCollections.dependencies, + options: { + projectName: project.metadata.name, + librariesPattern: !taskUtil.isRootProject() ? "/resources/**/*.library" : undefined, + themesPattern: !taskUtil.isRootProject() ? "/resources/sap/ui/core/themes/*" : undefined, + inputPattern: "/resources/**/themes/*/library.source.less" + } + }); + }); + + this.addTask("generateResourcesJson", () => { + return getTask("generateResourcesJson").task({ + workspace: resourceCollections.workspace, + dependencies: resourceCollections.dependencies, + options: { + projectName: project.metadata.name + } + }); + }); + } +} + +module.exports = ThemeLibraryBuilder; diff --git a/lib/types/themeLibrary/ThemeLibraryFormatter.js b/lib/types/themeLibrary/ThemeLibraryFormatter.js new file mode 100644 index 000000000..d5f53cfe9 --- /dev/null +++ b/lib/types/themeLibrary/ThemeLibraryFormatter.js @@ -0,0 +1,90 @@ +const log = require("@ui5/logger").getLogger("types:themeLibrary:ThemeLibraryFormatter"); +const path = require("path"); +const AbstractUi5Formatter = require("../AbstractUi5Formatter"); + + +class ThemeLibraryFormatter extends AbstractUi5Formatter { + /** + * Formats and validates the project + * + * @returns {Promise} + */ + async format() { + const project = this._project; + await this.validate(); + + log.verbose("Formatting theme-library project %s...", project.metadata.name); + project.resources.pathMappings = { + "/resources/": project.resources.configuration.paths.src + }; + + if (project.resources.configuration.paths.test) { + // Directory 'test' is somewhat optional for theme-libraries + project.resources.pathMappings["/test-resources/"] = project.resources.configuration.paths.test; + } else { + log.verbose(`Ignoring 'test' directory for project ${project.metadata.name}. ` + + "Either no setting was provided or the path not found."); + } + } + + /** + * Validates the project + * + * @returns {Promise} resolves if successfully validated + * @throws {Error} if validation fails + */ + validate() { + const project = this._project; + return Promise.resolve().then(() => { + if (!project) { + throw new Error("Project is undefined"); + } else if (project.specVersion === "0.1" || project.specVersion === "1.0") { + throw new Error( + `theme-library type requires "specVersion" 1.1 or higher. ` + + `Project "specVersion" is: ${project.specVersion}`); + } else if (!project.metadata || !project.metadata.name) { + throw new Error(`"metadata.name" configuration is missing for project ${project.id}`); + } else if (!project.type) { + throw new Error(`"type" configuration is missing for project ${project.id}`); + } else if (project.version === undefined) { + throw new Error(`"version" is missing for project ${project.id}`); + } + if (!project.resources) { + project.resources = {}; + } + if (!project.resources.configuration) { + project.resources.configuration = {}; + } + if (!project.resources.configuration.paths) { + project.resources.configuration.paths = {}; + } + if (!project.resources.configuration.paths.src) { + project.resources.configuration.paths.src = "src"; + } + if (!project.resources.configuration.paths.test) { + project.resources.configuration.paths.test = "test"; + } + + const absoluteSrcPath = path.join(project.path, project.resources.configuration.paths.src); + const absoluteTestPath = path.join(project.path, project.resources.configuration.paths.test); + return Promise.all([ + this.dirExists(absoluteSrcPath).then(function(bExists) { + if (!bExists) { + throw new Error(`Could not find source directory of project ${project.id}: ` + + `${absoluteSrcPath}`); + } + }), + this.dirExists(absoluteTestPath).then(function(bExists) { + if (!bExists) { + log.verbose(`Could not find (optional) test directory of project ${project.id}: ` + + `${absoluteTestPath}`); + // Current signal to following consumers that "test" is not available is null + project.resources.configuration.paths.test = null; + } + }) + ]); + }); + } +} + +module.exports = ThemeLibraryFormatter; diff --git a/lib/types/themeLibrary/themeLibraryType.js b/lib/types/themeLibrary/themeLibraryType.js new file mode 100644 index 000000000..5907e62d9 --- /dev/null +++ b/lib/types/themeLibrary/themeLibraryType.js @@ -0,0 +1,15 @@ +const ThemeLibraryFormatter = require("./ThemeLibraryFormatter"); +const ThemeLibraryBuilder = require("./ThemeLibraryBuilder"); + +module.exports = { + format: function(project) { + return new ThemeLibraryFormatter({project}).format(); + }, + build: function({resourceCollections, tasks, project, parentLogger, taskUtil}) { + return new ThemeLibraryBuilder({resourceCollections, project, parentLogger, taskUtil}).build(tasks); + }, + + // Export type classes for extensibility + Builder: ThemeLibraryBuilder, + Formatter: ThemeLibraryFormatter +}; diff --git a/lib/types/typeRepository.js b/lib/types/typeRepository.js index 7299a903d..5c2c8d574 100644 --- a/lib/types/typeRepository.js +++ b/lib/types/typeRepository.js @@ -1,18 +1,20 @@ const applicationType = require("./application/applicationType"); const libraryType = require("./library/libraryType"); +const themeLibraryType = require("./themeLibrary/themeLibraryType"); const moduleType = require("./module/moduleType"); const types = { - application: applicationType, - library: libraryType, - module: moduleType + "application": applicationType, + "library": libraryType, + "theme-library": themeLibraryType, + "module": moduleType }; /** * Gets a type * * @param {string} typeName unique identifier for the type - * @returns {Object} type identified by name + * @returns {object} type identified by name * @throws {Error} if not found */ function getType(typeName) { @@ -28,7 +30,7 @@ function getType(typeName) { * Adds a type * * @param {string} typeName unique identifier for the type - * @param {Object} type + * @param {object} type * @throws {Error} if duplicate with same name was found */ function addType(typeName, type) { diff --git a/package-lock.json b/package-lock.json index 1c90819cf..f086c0826 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,64 +1,37 @@ { "name": "@ui5/builder", - "version": "1.5.3", + "version": "2.4.5", "lockfileVersion": 1, "requires": true, "dependencies": { - "@ava/babel-plugin-throws-helper": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-4.0.0.tgz", - "integrity": "sha512-3diBLIVBPPh3j4+hb5lo0I1D+S/O/VDJPI4Y502apBxmwEqjyXG4gTSPFUlm41sSZeZzMarT/Gzovw9kV7An0w==", - "dev": true - }, - "@ava/babel-preset-stage-4": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-4.0.0.tgz", - "integrity": "sha512-lZEV1ZANzfzSYBU6WHSErsy7jLPbD1iIgAboASPMcKo7woVni5/5IKWeT0RxC8rY802MFktur3OKEw2JY1Tv2w==", - "dev": true, - "requires": { - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-dynamic-import": "^7.5.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/plugin-transform-modules-commonjs": "^7.5.0" - } - }, - "@ava/babel-preset-transform-test-files": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-6.0.0.tgz", - "integrity": "sha512-8eKhFzZp7Qcq1VLfoC75ggGT8nQs9q8fIxltU47yCB7Wi7Y8Qf6oqY1Bm0z04fIec24vEgr0ENhDHEOUGVDqnA==", - "dev": true, - "requires": { - "@ava/babel-plugin-throws-helper": "^4.0.0", - "babel-plugin-espower": "^3.0.1" - } - }, "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.10.4" } }, "@babel/core": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz", - "integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.4", - "@babel/helpers": "^7.6.2", - "@babel/parser": "^7.6.4", - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.3", - "@babel/types": "^7.6.3", - "convert-source-map": "^1.1.0", + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.9", + "@babel/types": "^7.12.7", + "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" @@ -79,14 +52,13 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.12.5", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" }, "dependencies": { @@ -98,262 +70,227 @@ } } }, - "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/types": "^7.10.4" } }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.12.5" } }, "@babel/helper-module-transforms": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", - "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/types": "^7.5.5", - "lodash": "^4.17.13" + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" } }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", - "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.7.tgz", + "integrity": "sha512-I5xc9oSJ2h59OwyUqjv95HRyzxj53DAubUERgQMrpcCEYQyToeHA+NEcUEsVWB4j53RDeskeBJ0SgRAYHDBckw==", "dev": true, "requires": { - "lodash": "^4.17.13" + "@babel/types": "^7.12.7" } }, - "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "@babel/helper-replace-supers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", "dev": true, "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/types": "^7.12.1" } }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.11.0" } }, - "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" - } + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true }, "@babel/helpers": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", - "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "dev": true, "requires": { - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.2", - "@babel/types": "^7.6.0" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0", - "@babel/plugin-syntax-async-generators": "^7.2.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", - "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz", - "integrity": "sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz", - "integrity": "sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==" }, "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz", + "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==", "dev": true, "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.13" + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, @@ -374,6 +311,66 @@ } } }, + "@eslint/eslintrc": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -404,33 +401,42 @@ "dev": true }, "@sinonjs/commons": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", - "integrity": "sha512-w4/WHG7C4WWFyE5geCieFJF6MZkbW4VAriol5KlmQXpAQdxvV0p26sqNZOW6Qyw6Y0l9K4g+cHvvczR2sEEpqg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { "type-detect": "4.0.8" } }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", + "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", "dev": true, "requires": { "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" + "@sinonjs/samsam": "^5.0.2" } }, "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.0.tgz", + "integrity": "sha512-hXpcfx3aq+ETVBwPlRFICld5EnrkexXuXDwqUNhDdr5L8VjvMeSRwyOa0qL7XFmR+jVWR4rUZtnxlG7RX72sBg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" } }, "@sinonjs/text-encoding": { @@ -448,86 +454,124 @@ "defer-to-connect": "^1.0.1" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + "@tokenizer/token": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.1.1.tgz", + "integrity": "sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w==", + "dev": true }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } + "@types/debug": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", + "dev": true }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true }, "@types/node": { - "version": "12.7.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.12.tgz", - "integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==" + "version": "14.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", + "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==", + "dev": true, + "optional": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } }, "@ui5/fs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ui5/fs/-/fs-1.1.2.tgz", - "integrity": "sha512-WKoHz5IA10jr2rl2BrmJG7RtEnkpLqkQX84phBT+7onX9I+Yv72MspHZCQbHpGoaJxt6G3TavggchZ7FKroGEw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@ui5/fs/-/fs-2.0.5.tgz", + "integrity": "sha512-jLkECzETgqUiRx9UBiJInaPQts7k+4tw9XUYVmvlXDGyY5kKJwA0RX0gqzVzAJeYgW+EvnwU1qHy9L0J0i1vTg==", "requires": { - "@ui5/logger": "^1.0.1", + "@ui5/logger": "^2.0.1", "clone": "^2.1.0", - "globby": "^10.0.0", - "graceful-fs": "^4.2.0", - "make-dir": "^3.0.0", + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "make-dir": "^3.1.0", "micromatch": "^4.0.2", "minimatch": "^3.0.3", - "mock-require": "^3.0.3", "pretty-hrtime": "^1.0.3", - "random-int": "^2.0.0", + "random-int": "^2.0.1", "slash": "^3.0.0" } }, "@ui5/logger": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@ui5/logger/-/logger-1.0.2.tgz", - "integrity": "sha512-k49q5D7EBk4vGzpM81KDNyGL4YaB12v8qYNqR7/5f4xoAksotf7h3VeAjCmJFSttEOnC9LNb9GYTzJAWJoCv7w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@ui5/logger/-/logger-2.0.1.tgz", + "integrity": "sha512-FU5moQF9HATZEIJVQxXWRsUKMveIRJNPSmH3Mptcuc05f6gKu1BWcamDaDHXmMSyoKRounY9Aok94NTQMi7eDw==", "requires": { "npmlog": "^4.1.2" } }, "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "acorn-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.0.0.tgz", + "integrity": "sha512-oZRad/3SMOI/pxbbmqyurIx7jHw1wZDcR9G44L8pUVFEomX/0dH89SrM1KaDXuv1NpzAXz6Op/Xu/Qd5XXzdEA==", "dev": true }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "optional": true - }, "ansi-align": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", @@ -577,14 +621,11 @@ } } }, - "ansi-escapes": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", - "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", - "dev": true, - "requires": { - "type-fest": "^0.5.2" - } + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true }, "ansi-regex": { "version": "2.1.1", @@ -592,29 +633,12 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.1.0.tgz", - "integrity": "sha512-Qts4KCLKG+waHc9C4m07weIY8qyeixoS0h6RnbsNVD6Fw+pEZGW3vTyObL3WXpE09Mq4Oi7/lBEyLmOiLtlYWQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" - }, - "dependencies": { - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, "anymatch": { @@ -625,23 +649,15 @@ "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - } } }, "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, "requires": { - "default-require-extensions": "^2.0.0" + "default-require-extensions": "^3.0.0" } }, "aproba": { @@ -668,15 +684,14 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "dev": true }, "array-events": { @@ -695,21 +710,15 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" }, - "array-uniq": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz", - "integrity": "sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==", + "arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", "dev": true }, "arrify": { @@ -718,19 +727,6 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -738,9 +734,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async-arrays": { @@ -752,176 +748,101 @@ "sift": "*" } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "ava": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ava/-/ava-2.4.0.tgz", - "integrity": "sha512-CQWtzZZZeU2g4StojRv6MO9RIRi4sLxGSB9+3C3hv0ttUEG1tkJLTLyrBQeFS4WEeK12Z4ovE3f2iPVhSy8elA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-3.13.0.tgz", + "integrity": "sha512-yzky+gark5PdsFFlZ4CnBVxm/OgBUWtn9vAsSSnuooVJNOk5ER17HJXVeUzy63LIt06Zy34oThcn+2ZqgMs7SA==", "dev": true, "requires": { - "@ava/babel-preset-stage-4": "^4.0.0", - "@ava/babel-preset-transform-test-files": "^6.0.0", - "@babel/core": "^7.6.0", - "@babel/generator": "^7.6.0", "@concordance/react": "^2.0.0", - "ansi-escapes": "^4.2.1", - "ansi-styles": "^4.1.0", - "arr-flatten": "^1.1.0", - "array-union": "^2.1.0", - "array-uniq": "^2.1.0", + "acorn": "^8.0.1", + "acorn-walk": "^8.0.0", + "ansi-styles": "^4.2.1", + "arrgv": "^1.0.2", "arrify": "^2.0.1", - "bluebird": "^3.5.5", - "chalk": "^2.4.2", - "chokidar": "^3.0.2", - "chunkd": "^1.0.0", - "ci-parallel-vars": "^1.0.0", - "clean-stack": "^2.2.0", + "callsites": "^3.1.0", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "chunkd": "^2.0.1", + "ci-info": "^2.0.0", + "ci-parallel-vars": "^1.0.1", "clean-yaml-object": "^0.1.0", "cli-cursor": "^3.1.0", - "cli-truncate": "^2.0.0", - "code-excerpt": "^2.1.1", - "common-path-prefix": "^1.0.0", - "concordance": "^4.0.0", - "convert-source-map": "^1.6.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.1", + "convert-source-map": "^1.7.0", "currently-unhandled": "^0.4.1", - "debug": "^4.1.1", - "del": "^4.1.1", - "dot-prop": "^5.1.0", - "emittery": "^0.4.1", - "empower-core": "^1.2.0", + "debug": "^4.2.0", + "del": "^6.0.0", + "emittery": "^0.7.1", "equal-length": "^1.0.0", - "escape-string-regexp": "^2.0.0", - "esm": "^3.2.25", - "figures": "^3.0.0", - "find-up": "^4.1.0", - "get-port": "^5.0.0", - "globby": "^10.0.1", - "ignore-by-default": "^1.0.0", + "figures": "^3.2.0", + "globby": "^11.0.1", + "ignore-by-default": "^2.0.0", "import-local": "^3.0.2", "indent-string": "^4.0.0", - "is-ci": "^2.0.0", "is-error": "^2.2.2", - "is-observable": "^2.0.0", - "is-plain-object": "^3.0.0", - "is-promise": "^2.1.0", - "lodash": "^4.17.15", - "loud-rejection": "^2.1.0", - "make-dir": "^3.0.0", - "matcher": "^2.0.0", + "is-plain-object": "^5.0.0", + "is-promise": "^4.0.0", + "lodash": "^4.17.20", + "matcher": "^3.0.0", "md5-hex": "^3.0.1", - "meow": "^5.0.0", - "micromatch": "^4.0.2", + "mem": "^6.1.1", "ms": "^2.1.2", - "observable-to-promise": "^1.0.0", - "ora": "^3.4.0", - "package-hash": "^4.0.0", + "ora": "^5.1.0", + "p-event": "^4.2.0", + "p-map": "^4.0.0", + "picomatch": "^2.2.2", "pkg-conf": "^3.1.0", - "plur": "^3.1.1", - "pretty-ms": "^5.0.0", - "require-precompiled": "^0.1.0", + "plur": "^4.0.0", + "pretty-ms": "^7.0.1", + "read-pkg": "^5.2.0", "resolve-cwd": "^3.0.0", "slash": "^3.0.0", - "source-map-support": "^0.5.13", - "stack-utils": "^1.0.2", - "strip-ansi": "^5.2.0", - "strip-bom-buf": "^2.0.0", + "source-map-support": "^0.5.19", + "stack-utils": "^2.0.2", + "strip-ansi": "^6.0.0", "supertap": "^1.0.0", - "supports-color": "^7.0.0", + "temp-dir": "^2.0.0", "trim-off-newlines": "^1.0.1", - "trim-right": "^1.0.1", - "unique-temp-dir": "^1.0.0", - "update-notifier": "^3.0.1", - "write-file-atomic": "^3.0.0" + "update-notifier": "^4.1.1", + "write-file-atomic": "^3.0.3", + "yargs": "^16.0.3" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-espower": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-3.0.1.tgz", - "integrity": "sha512-Ms49U7VIAtQ/TtcqRbD6UBmJBUCSxiC3+zPc+eGqxKUIFO1lTshyEDRUjhoAbd2rWfwYf3cZ62oXozrd8W6J0A==", - "dev": true, - "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "call-matcher": "^1.0.0", - "core-js": "^2.0.0", - "espower-location-detector": "^1.0.0", - "espurify": "^1.6.0", - "estraverse": "^4.1.1" - } - }, - "babylon": { - "version": "7.0.0-beta.19", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz", - "integrity": "sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A==" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, "bit-mask": { @@ -934,14 +855,14 @@ } }, "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "blueimp-md5": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.12.0.tgz", - "integrity": "sha512-zo+HIdIhzojv6F1siQPqPFROyVy7C50KzHv/k/Iz+BtvtVzSHXiMXOpq2wCfNkeBqdCv+V8XOV96tsEt2W/3rQ==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz", + "integrity": "sha512-vE52okJvzsVWhcgUHOv+69OG3Mdg151xyn41aVQN/5W5S+S43qZhxECtYLAEHMSFWX6Mv5IZrzj3T5+JqXfj5Q==", "dev": true }, "boolbase": { @@ -950,69 +871,67 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "boxen": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz", - "integrity": "sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "dev": true, "requires": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", - "chalk": "^2.4.2", + "chalk": "^3.0.0", "cli-boxes": "^2.2.0", - "string-width": "^3.0.0", - "term-size": "^1.2.0", - "type-fest": "^0.3.0", - "widest-line": "^2.0.0" + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } }, "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } @@ -1044,6 +963,12 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "dev": true + }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -1060,9 +985,9 @@ }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -1077,83 +1002,15 @@ } }, "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" - }, - "dependencies": { - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - } - } - }, - "call-matcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.1.0.tgz", - "integrity": "sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, "requires": { - "core-js": "^2.0.0", - "deep-equal": "^1.0.0", - "espurify": "^1.6.0", - "estraverse": "^4.0.0" + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" } }, "call-me-maybe": { @@ -1162,12 +1019,6 @@ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", "dev": true }, - "call-signature": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", - "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", - "dev": true - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1175,27 +1026,22 @@ "dev": true }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "catharsis": { "version": "0.8.11", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", @@ -1229,42 +1075,15 @@ } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1295,33 +1114,191 @@ } }, "chokidar": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.2.1.tgz", - "integrity": "sha512-/j5PPkb5Feyps9e+jo07jUZGvkB5Aj953NrI4s8xSVScrAo/RHeILrtdb4uzR7N6aaFFxxJ+gt8mA8HfNpw76w==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.0", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.1.3" + "readdirp": "~3.5.0" + } + }, + "chokidar-cli": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chokidar-cli/-/chokidar-cli-2.1.0.tgz", + "integrity": "sha512-6n21AVpW6ywuEPoxJcLXMA2p4T+SLjWsXKny/9yTWFz0kKxESI3eUylpeV97LylING/27T/RVTY0f2/0QaWq9Q==", + "dev": true, + "requires": { + "chokidar": "^3.2.3", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "yargs": "^13.3.0" }, "dependencies": { - "normalize-path": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, "chunkd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-1.0.0.tgz", - "integrity": "sha512-xx3Pb5VF9QaqCotolyZ1ywFBgyuJmu6+9dLiqBxgelEse9Xsr3yUlpoX3O4Oh11M00GT2kYMsRByTKIMJW2Lkg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", "dev": true }, "ci-info": { @@ -1331,20 +1308,11 @@ "dev": true }, "ci-parallel-vars": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.0.tgz", - "integrity": "sha512-u6dx20FBXm+apMi+5x7UVm6EH7BL1gc4XrcnQewjcB7HWRcor/V5qWc3RG2HwpgDJ26gIi2DSEu3B7sXynAw/g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", "dev": true }, - "clean-css": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-2.0.8.tgz", - "integrity": "sha1-6TfN/cxXgaAIF67EB56Fs+wVeiA=", - "optional": true, - "requires": { - "commander": "2.0.x" - } - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1358,9 +1326,9 @@ "dev": true }, "cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, "cli-cursor": { @@ -1373,25 +1341,25 @@ } }, "cli-spinners": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", - "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", + "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", "dev": true }, "cli-truncate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.0.0.tgz", - "integrity": "sha512-C4hp+8GCIFVsUUiXcw+ce+7wexVWImw8rQrgMBFsqerx9LvvcGlwm6sMjQYAEmV/Xb87xc1b5Ttx505MSpZVqg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "requires": { - "slice-ansi": "^2.1.0", - "string-width": "^4.1.0" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { @@ -1401,80 +1369,68 @@ "dev": true }, "string-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", - "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^5.2.0" + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } @@ -1494,9 +1450,9 @@ } }, "code-excerpt": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.1.tgz", - "integrity": "sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", "dev": true, "requires": { "convert-to-spaces": "^1.0.1" @@ -1508,44 +1464,35 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz", - "integrity": "sha1-0bhvkB+LZL2UG96tr5JFMDk76Sg=", - "optional": true + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "comment-parser": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.5.5.tgz", - "integrity": "sha512-oB3TinFT+PV3p8UwDQt71+HkG03+zwPwikDlKU6ZDmql6QX2zFlQ+G0GGSDqyJhdZi4PSlzFBm+YJ+ebOX3Vgw==", + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz", + "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==", "dev": true }, "common-path-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", - "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", "dev": true }, "commondir": { @@ -1559,109 +1506,34 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "concordance": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-4.0.0.tgz", - "integrity": "sha512-l0RFuB8RLfCS0Pt2Id39/oCPykE01pyxgAFypWTlaGRgvLkZrtczZ8atEHpTeEIW+zYWXTBuA9cCSeEOScxReQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.1.tgz", + "integrity": "sha512-TbNtInKVElgEBnJ1v2Xg+MFX2lvFLbmlv3EuSC5wTfCwpB8kC3w3mffF6cKuUhkn475Ym1f1I4qmuXzx2+uXpw==", "dev": true, "requires": { - "date-time": "^2.1.0", - "esutils": "^2.0.2", - "fast-diff": "^1.1.2", + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", "js-string-escape": "^1.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.flattendeep": "^4.4.0", - "lodash.islength": "^4.0.1", - "lodash.merge": "^4.6.1", - "md5-hex": "^2.0.0", - "semver": "^5.5.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", "well-known-symbols": "^2.0.0" - }, - "dependencies": { - "md5-hex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", - "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", - "dev": true, - "requires": { - "md5-o-matic": "^0.1.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "configstore": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", - "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dev": true, "requires": { - "dot-prop": "^4.1.0", + "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "dependencies": { - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - } + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" } }, "console-control-strings": { @@ -1670,9 +1542,9 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -1684,148 +1556,72 @@ "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", "dev": true }, - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "coveralls": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.7.tgz", - "integrity": "sha512-mUuH2MFOYB2oBaA4D4Ykqi9LaEYpMMlsiOMJOrv358yAjP6enPIk55fod2fNJ8AvwoYXStWQls37rA+s5e7boA==", - "dev": true, - "requires": { - "growl": "~> 1.10.0", - "js-yaml": "^3.13.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.86.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true } } }, "cross-env": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", - "integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, "requires": { - "cross-spawn": "^7.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", - "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz", - "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "cross-spawn": "^7.0.1" } }, "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", "requires": { - "inherits": "^2.0.3", + "inherits": "^2.0.4", "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" + "source-map-resolve": "^0.6.0" } }, "css-select": { @@ -1862,30 +1658,28 @@ "type": "^1.0.1" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "date-time": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-2.1.0.tgz", - "integrity": "sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", "dev": true, "requires": { "time-zone": "^1.0.0" } }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -1935,20 +1729,6 @@ "type-detect": "^4.0.0" } }, - "deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", - "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -1961,12 +1741,20 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", "dev": true, "requires": { - "strip-bom": "^3.0.0" + "strip-bom": "^4.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + } } }, "defaults": { @@ -1981,101 +1769,87 @@ "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - } - } - }, - "defer-to-connect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz", - "integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true } } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "del": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", + "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "dev": true, + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + } }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, + "depcheck": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-1.3.1.tgz", + "integrity": "sha512-lLMfqX2J+ZF3xUEqHpgCNk+dA8erAfW6XURGNAIyUS4KL2i3lezXGYDevYk3G0rWCwy/3CpxE8ek10NrURFOtQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.12.5", + "@babel/traverse": "^7.12.5", + "builtin-modules": "^3.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "deps-regex": "^0.1.4", + "ignore": "^5.1.8", + "js-yaml": "^3.14.0", + "json5": "^2.1.3", + "lodash": "^4.17.20", + "minimatch": "^3.0.4", + "multimatch": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "query-ast": "^1.0.3", + "readdirp": "^3.5.0", + "require-package-name": "^2.0.1", + "resolve": "^1.18.1", + "sass": "^1.29.0", + "scss-parser": "^1.0.4", + "semver": "^7.3.2", + "vue-template-compiler": "^2.6.12", + "yargs": "^16.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + } + } + }, + "deps-regex": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.1.4.tgz", + "integrity": "sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ=", + "dev": true + }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "dir-glob": { @@ -2087,9 +1861,9 @@ } }, "docdash": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/docdash/-/docdash-1.1.1.tgz", - "integrity": "sha512-WQkkr01zL6kcIfq9YCSXtqqevM6NYoTXLdl+Td0OYCEcX0RgsuEMeqHXQaXFt+p6Lo15RIgA5XhLAn7RL+erhA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/docdash/-/docdash-1.2.0.tgz", + "integrity": "sha512-IYZbgYthPTspgqYeciRJNPhSwL51yer7HAwDXhF5p+H7mTDbPvY3PCk/QDjNxdPCpWkaJVFC4t7iCNB/t9E5Kw==", "dev": true }, "doctrine": { @@ -2133,18 +1907,18 @@ } }, "dot-prop": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.1.0.tgz", - "integrity": "sha512-n1oC6NBF+KM9oVXtjmen4Yo7HyAVWV2UUl50dCYJdw2924K6dX9bf9TTTWaKtYlRn0FEtxG27KS80ayVLixxJA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { "is-obj": "^2.0.0" } }, "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, "duplexer2": { @@ -2162,19 +1936,10 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "emittery": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.4.1.tgz", - "integrity": "sha512-r4eRSeStEGf6M5SKdrQhhLK5bOwOBxQhIE3YSTnZE3GpKiLfnnhE+tPtrJE79+eDJgm39BM6LSoI8SCx4HbwlQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", "dev": true }, "emoji-regex": { @@ -2183,16 +1948,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "empower-core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-1.2.0.tgz", - "integrity": "sha512-g6+K6Geyc1o6FdXs9HwrXleCFan7d66G5xSCfSF7x1mJDCes6t0om9lFQG3zOrzh3Bkb/45N0cZ5Gqsf7YrzGQ==", - "dev": true, - "requires": { - "call-signature": "0.0.2", - "core-js": "^2.0.0" - } - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -2202,6 +1957,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", @@ -2222,41 +1986,14 @@ "is-arrayish": "^0.2.1" } }, - "es-abstract": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", - "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "es5-ext": { - "version": "0.10.51", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.51.tgz", - "integrity": "sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==", + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", "requires": { "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "^1.0.0" + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" } }, "es6-error": { @@ -2318,12 +2055,12 @@ } }, "es6-symbol": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.2.tgz", - "integrity": "sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "requires": { "d": "^1.0.1", - "es5-ext": "^0.10.51" + "ext": "^1.1.2" } }, "es6-weak-map": { @@ -2337,10 +2074,22 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" }, "escape-unicode": { "version": "0.2.0", @@ -2348,21 +2097,21 @@ "integrity": "sha512-7jMQuKb8nm0h/9HYLfu4NCLFwoUsd5XO6OZ1z86PbKcMf8zDK1m7nFR0iA2CCShq4TSValaLIveE8T1UBxgALQ==" }, "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", + "esprima": "^4.0.1", + "estraverse": "^5.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" } } }, @@ -2375,69 +2124,73 @@ "es6-weak-map": "^2.0.1", "esrecurse": "^4.1.0", "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } } }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", + "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "@eslint/eslintrc": "^0.2.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash": "^4.17.19", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "type-fest": "^0.8.1" } }, "ignore": { @@ -2446,137 +2199,182 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, "eslint-config-google": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.13.0.tgz", - "integrity": "sha512-ELgMdOIpn0CFdsQS+FuxO+Ttu4p+aLaXHv9wA9yVnzqlUGV7oN/eRRnJekk7TCur6Cu2FXX0fqfIXRBaM14lpQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", "dev": true }, "eslint-plugin-jsdoc": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-4.8.4.tgz", - "integrity": "sha512-VDP+BI2hWpKNNdsJDSPofSQ9q7jGLgWbDMI0LzOeEcfsTjSS7jQtHDUuVLQ5E+OV2MPyQPk/3lnVcHfStXk5yA==", + "version": "30.7.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.7.8.tgz", + "integrity": "sha512-OWm2AYvXjCl7nRbpcw5xisfSVkpVAyp4lGqL9T+DeK4kaPm6ecnmTc/G5s1PtcRrwbaI8bIWGzwScqv5CdGyxA==", "dev": true, "requires": { - "comment-parser": "^0.5.4", - "jsdoctypeparser": "3.1.0", - "lodash": "^4.17.11" + "comment-parser": "^0.7.6", + "debug": "^4.2.0", + "jsdoctypeparser": "^9.0.0", + "lodash": "^4.17.20", + "regextras": "^0.7.1", + "semver": "^7.3.2", + "spdx-expression-parse": "^3.0.1" } }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", "dev": true }, - "espower-location-detector": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", - "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "is-url": "^1.2.1", - "path-is-absolute": "^1.0.0", - "source-map": "^0.5.0", - "xtend": "^4.0.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, - "espurify": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz", - "integrity": "sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg==", - "dev": true, - "requires": { - "core-js": "^2.0.0" - } - }, "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } } }, "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==" }, "esutils": { "version": "2.0.3", @@ -2598,93 +2396,59 @@ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "type": "^2.0.0" }, "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "extended-emitter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/extended-emitter/-/extended-emitter-1.0.3.tgz", - "integrity": "sha512-gdaWWszJmr2oq6rKSxPmuclQtEwfzt4JwmGrEqTnE89GQHqZyvPZ/NWj6fBgK3IKufvRyJDnLZviUFPrrJf36Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/extended-emitter/-/extended-emitter-1.0.4.tgz", + "integrity": "sha512-QBGuIo+pCXnYNeLUObaH/IKrCrzWzm4KhQNvA/mwNTs7/wzFylmA765zxh0WwWqpX1skQGXvzcRMHScc87Om/g==", "dev": true, "requires": { "sift": "*", "wolfy87-eventemitter": "*" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { - "ms": "2.0.0" + "pump": "^3.0.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "fast-diff": { "version": "1.2.0", @@ -2693,21 +2457,23 @@ "dev": true }, "fast-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", - "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.0", "merge2": "^1.3.0", - "micromatch": "^4.0.2" + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" } }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -2715,45 +2481,59 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fastq": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", - "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", + "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", "requires": { - "reusify": "^1.0.0" + "reusify": "^1.0.4" } }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "~1.2.0" } }, "figures": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", - "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-type": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", - "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==", - "dev": true + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-14.7.1.tgz", + "integrity": "sha512-sXAMgFk67fQLcetXustxfKX+PZgHIUFn96Xld9uH8aXPdX3xOp0/jg9OdouVTvQrf7mrn+wAa4jN/y9fUOOiRA==", + "dev": true, + "requires": { + "readable-web-to-node-stream": "^2.0.0", + "strtok3": "^6.0.3", + "token-types": "^2.0.0", + "typedarray-to-buffer": "^3.1.5" + } }, "fill-range": { "version": "7.0.1", @@ -2764,75 +2544,14 @@ } }, "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, "find-up": { @@ -2846,69 +2565,36 @@ } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", "dev": true }, "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - } + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true }, "fs.realpath": { "version": "1.0.0", @@ -2916,16 +2602,17 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.0.tgz", - "integrity": "sha512-+iXhW3LuDQsno8dOIrCIT/CBjeBWuP7PXe8w9shnj9Lebny/Gx1ZjVBYwexLz36Ri2jKuXMNpV6CYNh8lHHgrQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, "optional": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -2948,10 +2635,17 @@ "wide-align": "^1.1.0" } }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "get-func-name": { "version": "2.0.0", @@ -2959,22 +2653,11 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-port": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.0.0.tgz", - "integrity": "sha512-imzMU0FjsZqNa6BqOjbbW6w5BivHIuQKopjpPqcnx0AVHJQKCxK1O+Ab3OrVXhrekqfVMjwA9ZYu062R+KcIsQ==", - "dev": true, - "requires": { - "type-fest": "^0.3.0" - }, - "dependencies": { - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true - } - } + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true }, "get-stdin": { "version": "7.0.0", @@ -2983,23 +2666,18 @@ "dev": true }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, "requires": { - "assert-plus": "^1.0.0" + "pump": "^3.0.0" } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3010,9 +2688,9 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "requires": { "is-glob": "^4.0.1" } @@ -3024,12 +2702,12 @@ "dev": true }, "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", "dev": true, "requires": { - "ini": "^1.3.4" + "ini": "^1.3.5" } }, "globals": { @@ -3039,17 +2717,15 @@ "dev": true }, "globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "requires": { - "@types/glob": "^7.1.1", "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", "slash": "^3.0.0" } }, @@ -3070,60 +2746,24 @@ "p-cancelable": "^1.0.0", "to-readable-stream": "^1.0.0", "url-parse-lax": "^3.0.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, - "handlebars": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.3.tgz", - "integrity": "sha512-B0W4A2U1ww3q7VVthTKfh+epHx+q4mCt6iK+zEAzbMBpWQAwxCeKxEGpj/1oQTpzPXDNSOG7hmG14TsISH50yw==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -3138,16 +2778,11 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -3160,9 +2795,9 @@ "dev": true }, "hasha": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.1.0.tgz", - "integrity": "sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, "requires": { "is-stream": "^2.0.0", @@ -3177,10 +2812,22 @@ } } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "htmlparser2": { @@ -3197,9 +2844,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3209,45 +2856,32 @@ } }, "http-cache-semantics": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", - "integrity": "sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true }, "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==" + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.0.0.tgz", + "integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA==", "dev": true }, "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -3310,138 +2944,19 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } - } + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" } }, "irregular-plurals": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", - "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==", - "dev": true - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", + "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", "dev": true }, "is-arrayish": { @@ -3459,11 +2974,6 @@ "binary-extensions": "^2.0.0" } }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" - }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -3473,10 +2983,20 @@ "ci-info": "^2.0.0" } }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "dev": true }, "is-error": { "version": "2.2.2", @@ -3506,30 +3026,25 @@ } }, "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", "dev": true, "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - }, - "dependencies": { - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - } + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, "is-npm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-3.0.0.tgz", - "integrity": "sha512-wsigDr1Kkschp2opC4G3yA6r9EgVA6NjRpWzIi9axXqeIaAATPRJc4uLujXe3Nd9uO8KoDyA4MD6aZSeXTADhA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, "is-number": { @@ -3543,35 +3058,17 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, - "is-observable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.0.0.tgz", - "integrity": "sha512-fhBZv3eFKUbyHXZ1oHujdo2tZ+CNbdpdzzlENgCGZUC8keoGxUew2jYFLYcUB4qo7LDD03o4KK11m/QYD7kEjg==", - "dev": true - }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true }, "is-plain-obj": { "version": "1.1.0", @@ -3580,64 +3077,43 @@ "dev": true }, "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true }, "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "dev": true }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "requires": { - "has-symbols": "^1.0.0" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } }, "is-yarn-global": { "version": "0.3.0", @@ -3656,132 +3132,97 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true }, "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, "requires": { - "append-transform": "^1.0.0" + "append-transform": "^2.0.0" } }, "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", "dev": true, "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" }, "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "requires": { - "glob": "^7.1.3" + "aggregate-error": "^3.0.0" } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true } } }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", "dev": true, "requires": { - "handlebars": "^4.1.2" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" } }, "js-string-escape": { @@ -3797,9 +3238,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3807,41 +3248,38 @@ } }, "js2xmlparser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz", - "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", + "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", "requires": { - "xmlcreate": "^1.0.1" + "xmlcreate": "^2.0.3" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, "jsdoc": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz", - "integrity": "sha512-6PxB65TAU4WO0Wzyr/4/YhlGovXl0EVYfpKbpSroSj0qBxT4/xod/l40Opkm38dRHRdQgdeY836M0uVnJQG7kg==", - "requires": { - "babylon": "7.0.0-beta.19", - "bluebird": "~3.5.0", - "catharsis": "~0.8.9", - "escape-string-regexp": "~1.0.5", - "js2xmlparser": "~3.0.0", - "klaw": "~2.0.0", - "marked": "~0.3.6", - "mkdirp": "~0.5.1", - "requizzle": "~0.2.1", - "strip-json-comments": "~2.0.1", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz", + "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==", + "requires": { + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", + "catharsis": "^0.8.11", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.1", + "klaw": "^3.0.0", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^0.8.2", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", - "underscore": "~1.8.3" + "underscore": "~1.10.2" } }, "jsdoctypeparser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-3.1.0.tgz", - "integrity": "sha512-JNbkKpDFqbYjg+IU3FNo7qjX7Opy7CwjHywT32zgAcz/d4lX6Umn5jOHVETUdnNNgGrMk0nEx1gvP0F4M0hzlQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==", "dev": true }, "jsesc": { @@ -3862,15 +3300,17 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3878,43 +3318,19 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "minimist": "^1.2.5" } }, "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", + "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", "dev": true }, "keyv": { @@ -3926,10 +3342,16 @@ "json-buffer": "3.0.0" } }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, "klaw": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz", - "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "requires": { "graceful-fs": "^4.1.9" } @@ -3943,50 +3365,14 @@ "package-json": "^6.3.0" } }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", - "dev": true - }, - "less": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/less/-/less-1.6.3.tgz", - "integrity": "sha1-cc6J7DC3dLNWfyVMZ5WPLywZO94=", - "requires": { - "clean-css": "2.0.x", - "mime": "1.2.x", - "mkdirp": "~0.3.5", - "request": ">=2.12.0", - "source-map": "0.1.x" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "optional": true - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, "less-openui5": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/less-openui5/-/less-openui5-0.6.0.tgz", - "integrity": "sha512-Ncv9fhCkpssBut4Cefqfbf4IRVk8dz44LQJ80zHB6WG9BBsuqoLvWUxbV1VhxRJVGsDNbDcGb2i5s0KvoXJqdg==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/less-openui5/-/less-openui5-0.9.0.tgz", + "integrity": "sha512-RwZJ7ZXEJwv2HTeuZp6JJzfbZFMlMyXyWuqH95n+roDy+8EpI3nQdvMhxYG5fzciJ+c5ACrNhoZ7Nv2xqkEmig==", "requires": { "clone": "^2.1.0", - "css": "^2.2.1", - "less": "1.6.3", - "object-assign": "^4.0.1" + "css": "^3.0.0", + "mime": "^1.6.0" } }, "levn": { @@ -3998,24 +3384,31 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.1.15", "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" } }, "locate-path": { @@ -4028,9 +3421,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.assignin": { "version": "4.2.0", @@ -4042,10 +3435,10 @@ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, "lodash.defaults": { @@ -4074,10 +3467,10 @@ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" }, - "lodash.islength": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.islength/-/lodash.islength-4.0.1.tgz", - "integrity": "sha1-Tpho1FJXXXUK/9NYyXlUPcIO1Xc=", + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, "lodash.map": { @@ -4110,35 +3503,28 @@ "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^4.0.0" } }, - "lolex": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", - "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", - "dev": true - }, - "loud-rejection": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-2.2.0.tgz", - "integrity": "sha512-S0FayMXku80toa5sZ6Ro4C+s+EtFDCsyJNG/AzFMfX3AxD5Si4dZsgzm/kKnbOxHl5Cv8jBlno8+3XYIh2pNjQ==", + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.2" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "lowercase-keys": { @@ -4148,47 +3534,85 @@ "dev": true }, "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" } }, "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "requires": { "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" } }, "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" + } + } + }, + "markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==" + }, "marked": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", - "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==" + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", + "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==" }, "matcher": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.0.0.tgz", - "integrity": "sha512-nlmfSlgHBFx36j/Pl/KQPbIaqE8Zf0TqmSMjsuddHDg6PMSVgmyW9HpkLs0o0M1n2GIZ/S2BZBLIww/xjhiGng==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "escape-string-regexp": "^4.0.0" }, "dependencies": { "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true } } @@ -4202,54 +3626,70 @@ "blueimp-md5": "^2.10.0" } }, - "md5-o-matic": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", - "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", - "dev": true + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "mem": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz", + "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true + } + } }, "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", + "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" }, "dependencies": { - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { "version": "4.0.2", @@ -4261,23 +3701,9 @@ } }, "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", - "optional": true - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mimic-fn": { "version": "2.1.0", @@ -4291,6 +3717,12 @@ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -4300,18 +3732,20 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" }, "dependencies": { "arrify": { @@ -4323,20 +3757,35 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "mock-require": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", + "dev": true, "requires": { "get-caller-file": "^1.0.2", "normalize-path": "^2.1.1" + }, + "dependencies": { + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "ms": { @@ -4345,10 +3794,23 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + } + }, "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, "natural-compare": { @@ -4357,42 +3819,33 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "nise": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", - "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", + "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", "dev": true, "requires": { - "@sinonjs/formatio": "^3.2.1", + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", - "lolex": "^4.1.0", "path-to-regexp": "^1.7.0" } }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -4414,12 +3867,10 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "normalize-url": { "version": "4.5.0", @@ -4427,15 +3878,6 @@ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", "dev": true }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -4461,113 +3903,132 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "locate-path": { + "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "aggregate-error": "^3.0.0" } }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "ansi-regex": "^5.0.0" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { - "glob": "^7.1.3" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -4576,63 +4037,11 @@ } } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" - }, - "object-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", - "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "observable-to-promise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-1.0.0.tgz", - "integrity": "sha512-cqnGUrNsE6vdVDTPAX9/WeVzwy/z37vdxupdQXU8vgTXRFH72KCZiZga8aca2ulRPIeem8W3vW9rQHBwfIl2WA==", - "dev": true, - "requires": { - "is-observable": "^2.0.0", - "symbol-observable": "^1.0.4" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4642,150 +4051,104 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", + "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", "dev": true, "requires": { - "is-wsl": "^1.1.0" + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" } }, "open-cli": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/open-cli/-/open-cli-5.0.0.tgz", - "integrity": "sha512-Y2KQDS6NqNtk+PSXzSgwH41vTDMRndwFgVWsfgMhXv7lNe1cImLCe19Vo8oKwMsL7WeNsGmmbX7Ml74Ydj61Cg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/open-cli/-/open-cli-6.0.1.tgz", + "integrity": "sha512-A5h8MF3GrT1efn9TiO9LPajDnLtuEiGQT5G8TxWObBlgt1cZJF1YbQo/kNtsD1bJb7HxnT6SaSjzeLq0Rfhygw==", "dev": true, "requires": { - "file-type": "^11.0.0", + "file-type": "^14.1.4", "get-stdin": "^7.0.0", - "meow": "^5.0.0", - "open": "^6.3.0", + "meow": "^6.1.0", + "open": "^7.0.3", "temp-write": "^4.0.0" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "requires": { "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "word-wrap": "~1.2.3" } }, "ora": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", - "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.1.0.tgz", + "integrity": "sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==", "dev": true, "requires": { - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-spinners": "^2.0.0", - "log-symbols": "^2.2.0", - "strip-ansi": "^5.2.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.4.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "requires": { + "p-timeout": "^3.1.0" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -4793,9 +4156,9 @@ "dev": true }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4811,10 +4174,22 @@ } }, "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } }, "p-try": { "version": "2.2.0", @@ -4844,6 +4219,14 @@ "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "parent-module": { @@ -4882,16 +4265,10 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { @@ -4901,9 +4278,9 @@ "dev": true }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" @@ -4928,21 +4305,22 @@ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "peek-readable": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-3.1.0.tgz", + "integrity": "sha512-KGuODSTV6hcgdZvDrIDBUkN0utcAVj1LL7FfGbM0viKTtCHmtZcuEJ+lGqsp0fTFkGqesdtemV2yUSMeyy3ddA==", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pify": { "version": "4.0.1", @@ -4950,21 +4328,6 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pkg-conf": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", @@ -4984,19 +4347,6 @@ "locate-path": "^3.0.0" } }, - "load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - } - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -5021,12 +4371,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true } } }, @@ -5039,13 +4383,22 @@ "find-up": "^4.0.0" } }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "plur": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", - "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", "dev": true, "requires": { - "irregular-plurals": "^2.0.0" + "irregular-plurals": "^3.2.0" } }, "prelude-ls": { @@ -5070,9 +4423,9 @@ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, "pretty-ms": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-5.0.0.tgz", - "integrity": "sha512-94VRYjL9k33RzfKiGokPBPpsmloBYSf5Ri+Pq19zlsEcUKFob+admeXr5eFDRuPjFmEOcjJvPGdillYOJyvZ7Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", "dev": true, "requires": { "parse-ms": "^2.1.0" @@ -5083,23 +4436,21 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -5113,17 +4464,32 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "query-ast": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/query-ast/-/query-ast-1.0.3.tgz", + "integrity": "sha512-k7z4jilpZCujhiJ+QeKSwYXHc9HxqiVKlVE7/em0zBfPpcqnXKUP8F7ld7XaAkO6oXeAD7yonqcNJWqOF2pSGA==", + "dev": true, + "requires": { + "invariant": "2.2.2", + "lodash": "^4.17.15" + } }, "quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "random-int": { @@ -5143,107 +4509,69 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true } } }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" }, "dependencies": { - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "dev": true, "requires": { - "pify": "^3.0.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true } } }, "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5254,6 +4582,12 @@ "util-deprecate": "~1.0.1" } }, + "readable-web-to-node-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-2.0.0.tgz", + "integrity": "sha512-+oZJurc4hXpaaqsN68GoZGQAQIA3qr09Or4fqEsargABnbe5Aau8hFn6ISVleT3cpY/0n/8drn7huyyEvTbghA==", + "dev": true + }, "readdir-enhanced": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/readdir-enhanced/-/readdir-enhanced-1.5.2.tgz", @@ -5266,12 +4600,12 @@ } }, "readdirp": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.3.tgz", - "integrity": "sha512-ZOsfTGkjO2kqeR5Mzr5RYDbTGYneSkdNKX2fOX2P5jF7vMrd/GNnIAUtDldeHHumHUCQ3V05YfWUdxMPAsRu9Q==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { - "picomatch": "^2.0.4" + "picomatch": "^2.2.1" } }, "recursive-readdir": { @@ -5284,75 +4618,34 @@ } }, "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - }, - "dependencies": { - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - } - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regexp.prototype.flags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", - "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "define-properties": "^1.1.2" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", "dev": true }, - "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", - "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, "registry-auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz", - "integrity": "sha512-lpQkHxd9UL6tb3k/aHAVfnVtn+Bcs9ob5InuFLLEDqSqeq+AljB8GZW9xY0x7F+xYwEcjKe07nyoxzEYz6yvkw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { - "rc": "^1.2.8", - "safe-buffer": "^5.0.1" + "rc": "^1.2.8" } }, "registry-url": { @@ -5364,29 +4657,6 @@ "rc": "^1.2.8" } }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -5399,7 +4669,8 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true }, "replacestream": { "version": "4.0.3", @@ -5409,33 +4680,13 @@ "escape-string-regexp": "^1.0.3", "object-assign": "^4.0.1", "readable-stream": "^2.0.2" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } } }, "require-directory": { @@ -5450,10 +4701,10 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "require-precompiled": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", - "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", + "require-package-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz", + "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk=", "dev": true }, "requizzle": { @@ -5465,11 +4716,12 @@ } }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, @@ -5488,11 +4740,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -5518,69 +4765,85 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" - }, - "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==" }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "sass": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.30.0.tgz", + "integrity": "sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw==", + "dev": true, + "requires": { + "chokidar": ">=2.0.0 <4.0.0" + } }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "scss-parser": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/scss-parser/-/scss-parser-1.0.4.tgz", + "integrity": "sha512-oDZwDfY2JhnDrHNZPcdcPNVTpAXsJBY2/uhFfN0IzMy1xExAfJDcI1Yl/VXhfRsdQL3wLeg6/Oxt3cafBOuMzQ==", + "dev": true, + "requires": { + "invariant": "2.2.4", + "lodash": "^4.17.4" + }, + "dependencies": { + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true }, "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "dev": true, "requires": { - "semver": "^5.0.3" + "semver": "^6.3.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -5597,55 +4860,44 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "sift": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/sift/-/sift-8.5.0.tgz", - "integrity": "sha512-IdHwlvlDbHYmcPYOfkU89Qo29cPR7fLM0htfeUP9YxeU213oKYH/6d416z+vFj6ArCsH+AzQQ8/rd1TIzRE7LQ==", + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-13.4.0.tgz", + "integrity": "sha512-sJAs3ujQjx6QVzWPKmqK1LhTAnpEiP2Q7zJi4VSmRYGAuz9SmlyAzo8w4jJQrrGXJb/QNUd0iJvD17dRezzfAA==", "dev": true }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "sinon": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz", - "integrity": "sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.4.0", - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/samsam": "^3.3.3", - "diff": "^3.5.0", - "lolex": "^4.2.0", - "nise": "^1.5.2", - "supports-color": "^5.5.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz", + "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/formatio": "^5.0.1", + "@sinonjs/samsam": "^5.2.0", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" } }, "slash": { @@ -5654,29 +4906,20 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true } } @@ -5687,60 +4930,41 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" } }, "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", "signal-exit": "^3.0.2", - "which": "^1.3.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "which": "^2.0.1" } }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -5748,15 +4972,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -5764,39 +4988,25 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "escape-string-regexp": "^2.0.0" } }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -5807,24 +5017,6 @@ "strip-ansi": "^3.0.0" } }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5847,31 +5039,30 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "strip-bom-buf": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-2.0.0.tgz", - "integrity": "sha512-gLFNHucd6gzb8jMsl5QmZ3QgnUJmp7qn4uUSHNwEXumAp7YizoGYw19ZUVfuq4aBOQUtyn2k8X/CwzWB73W2lQ==", + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { - "is-utf8": "^0.2.1" + "min-indent": "^1.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "strtok3": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.0.4.tgz", + "integrity": "sha512-rqWMKwsbN9APU47bQTMEYTPcwdpKDtmf1jVhHzNW2cL1WqAxaM9iBb9t5P2fj+RV2YsErUWgQzHD5JwV0uCTEQ==", + "dev": true, + "requires": { + "@tokenizer/token": "^0.1.1", + "@types/debug": "^4.1.5", + "peek-readable": "^3.1.0" + } }, "supertap": { "version": "1.0.0", @@ -5916,28 +5107,14 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - } } }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true - }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -5956,6 +5133,36 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -5968,6 +5175,17 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -6034,6 +5252,12 @@ } } }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", @@ -6076,12 +5300,6 @@ "xtend": "~4.0.0" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "tap-parser": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.2.2.tgz", @@ -6106,9 +5324,9 @@ } }, "temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "dev": true }, "temp-write": { @@ -6122,104 +5340,56 @@ "make-dir": "^3.0.0", "temp-dir": "^1.0.0", "uuid": "^3.3.2" - } - }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, - "requires": { - "execa": "^0.7.0" - } - }, - "terser": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.8.tgz", - "integrity": "sha512-otmIRlRVmLChAWsnSFNO0Bfk6YySuBp6G9qrHiJwlLDd4mxe2ta4sjI7TzIR+W1nBMjilzrMcPOz9pSusgx3hQ==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" }, "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true } } - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "terser": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", + "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" } } }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -6236,15 +5406,6 @@ "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", "dev": true }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -6265,26 +5426,20 @@ "is-number": "^7.0.0" } }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "token-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-2.0.0.tgz", + "integrity": "sha512-WWvu8sGK8/ZmGusekZJJ5NM6rRVTTDO7/bahz4NGiSDb/XsmdYBn6a1N/bymUHuWYTWeuLUg98wUzvE4jPdCZw==", + "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } + "@tokenizer/token": "^0.1.0", + "ieee754": "^1.1.13" } }, "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", "dev": true }, "trim-off-newlines": { @@ -6293,31 +5448,6 @@ "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -6338,15 +5468,9 @@ "dev": true }, "type-fest": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", - "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "dev": true }, "typedarray-to-buffer": { @@ -6358,118 +5482,67 @@ "is-typedarray": "^1.0.0" } }, - "uglify-js": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.1.tgz", - "integrity": "sha512-+dSJLJpXBb6oMHP+Yvw8hUgElz4gLTh82XuX68QiJVTXaE5ibl6buzhNkQdYhBlIhozWOC9ge16wyRmjG4TwVQ==", - "dev": true, - "optional": true, - "requires": { - "commander": "2.20.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true, - "optional": true - } - } - }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", - "dev": true + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==" }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dev": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unique-temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", - "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "requires": { - "mkdirp": "^0.5.1", - "os-tmpdir": "^1.0.1", - "uid2": "0.0.3" + "crypto-random-string": "^2.0.0" } }, "update-notifier": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-3.0.1.tgz", - "integrity": "sha512-grrmrB6Zb8DUiyDIaeRTBCkgISYUgETNe7NglEbVsrLWXeESnlCSP50WfRSj/GmzMPl6Uchj24S/p80nP/ZQrQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", "dev": true, "requires": { - "boxen": "^3.0.0", - "chalk": "^2.0.1", - "configstore": "^4.0.0", + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", - "is-installed-globally": "^0.1.0", - "is-npm": "^3.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", "is-yarn-global": "^0.3.0", "latest-version": "^5.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, "requires": { "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", @@ -6484,19 +5557,17 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true }, "validate-npm-package-license": { "version": "3.0.4", @@ -6508,14 +5579,14 @@ "spdx-expression-parse": "^3.0.0" } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "vue-template-compiler": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz", + "integrity": "sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==", + "dev": true, "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "de-indent": "^1.0.2", + "he": "^1.1.0" } }, "wcwidth": { @@ -6534,9 +5605,9 @@ "dev": true }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -6557,114 +5628,100 @@ } }, "widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { - "string-width": "^2.1.1" + "string-width": "^4.0.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } } } }, "wolfy87-eventemitter": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.8.tgz", - "integrity": "sha512-Z+wAU9SyuOZgFj22zBl8sg0auJOkrKBZl8TTlEM5dRDDs2zPtlm72vPJUIlf6tUJ4w2JLgrF7VznRnQHP+Rn/Q==", + "version": "5.2.9", + "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz", + "integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==", "dev": true }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } @@ -6674,19 +5731,10 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.0.tgz", - "integrity": "sha512-EIgkf60l2oWsffja2Sf2AL384dx328c0B+cIYPTQq5q2rOYuDV00/iPFBOUiDKKwKMOhkymH8AidPaRvzfxY+Q==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { "imurmurhash": "^0.1.4", @@ -6696,18 +5744,17 @@ } }, "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, "xml2js": { - "version": "0.4.22", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz", - "integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==", + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", "requires": { "sax": ">=0.6.0", - "util.promisify": "~1.0.0", "xmlbuilder": "~11.0.0" } }, @@ -6717,9 +5764,9 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" }, "xmlcreate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz", - "integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", + "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==" }, "xtend": { "version": "4.0.2", @@ -6728,147 +5775,85 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "ansi-regex": "^5.0.0" } } } }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { - "fd-slicer": "~1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } }, "yazl": { diff --git a/package.json b/package.json index 3ed0c837d..f49d03a37 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,12 @@ { "name": "@ui5/builder", - "version": "1.5.3", + "version": "2.4.5", "description": "UI5 Tooling - Builder", - "author": "SAP SE (https://www.sap.com)", + "author": { + "name": "SAP SE", + "email": "openui5@sap.com", + "url": "https://www.sap.com" + }, "license": "Apache-2.0", "keywords": [ "openui5", @@ -14,42 +18,44 @@ ], "main": "index.js", "engines": { - "node": ">= 8.5", + "node": ">= 10", "npm": ">= 5" }, "scripts": { - "test": "npm run lint && npm run jsdoc-generate && npm run coverage", - "test-azure": "npm run lint && npm run jsdoc-generate && npm run coverage-xunit", + "test": "npm run lint && npm run jsdoc-generate && npm run coverage && npm run depcheck", + "test-azure": "npm run coverage-xunit", "lint": "eslint ./", "unit": "rimraf test/tmp && ava", "unit-verbose": "rimraf test/tmp && cross-env UI5_LOG_LVL=verbose ava --verbose --serial", "unit-watch": "rimraf test/tmp && ava --watch", "unit-nyan": "rimraf test/tmp && ava --tap | tnyan", - "unit-xunit": "rimraf test/tmp && ava --tap | tap-xunit --dontUseCommentsAsTestNames=true > test-results.xml", - "unit-inspect": "cross-env UI5_LOG_LVL=verbose node --inspect-brk node_modules/ava/profile.js", + "unit-xunit": "rimraf test/tmp && ava --tap --timeout=1m | tap-xunit --dontUseCommentsAsTestNames=true > test-results.xml", + "unit-inspect": "cross-env UI5_LOG_LVL=verbose ava debug --break", "coverage": "nyc npm run unit", "coverage-xunit": "nyc --reporter=text --reporter=text-summary --reporter=cobertura npm run unit-xunit", "jsdoc": "npm run jsdoc-generate && open-cli jsdocs/index.html", "jsdoc-generate": "node_modules/.bin/jsdoc -c ./jsdoc.json ./lib/ || (echo 'Error during JSDoc generation! Check log.' && exit 1)", + "jsdoc-watch": "npm run jsdoc && chokidar \"./lib/**/*.js\" -c \"npm run jsdoc-generate\"", "preversion": "npm test", "version": "git-chglog --next-tag v$npm_package_version -o CHANGELOG.md && git add CHANGELOG.md", "postversion": "git push --follow-tags", "release-note": "git-chglog -c .chglog/release-config.yml v$npm_package_version", - "report-coveralls": "nyc report --reporter=text-lcov | COVERALLS_PARALLEL=true coveralls" + "depcheck": "depcheck --ignores docdash" }, "files": [ "index.js", "CONTRIBUTING.md", "jsdoc.json", - "lib/**" + "lib/**", + "LICENSES/**", + ".reuse/**" ], "ava": { "files": [ "test/lib/**/*.js" ], - "sources": [ - "lib/**/*.js", - "test/lib/**/*.js" + "ignoredByWatcher": [ + "test/tmp/**" ] }, "nyc": { @@ -59,12 +65,13 @@ "text-summary" ], "exclude": [ - ".eslintrc.js", + "lib/processors/jsdoc/lib/**", "docs/**", "jsdocs/**", "coverage/**", "test/**", - "lib/processors/jsdoc/lib/**" + ".eslintrc.js", + "jsdoc-plugin.js" ], "check-coverage": true, "statements": 85, @@ -97,45 +104,46 @@ "url": "git@github.com:SAP/ui5-builder.git" }, "dependencies": { - "@ui5/fs": "^1.1.2", - "@ui5/logger": "^1.0.2", + "@ui5/fs": "^2.0.5", + "@ui5/logger": "^2.0.1", "cheerio": "^0.22.0", "escape-unicode": "^0.2.0", - "escodegen": "^1.12.0", + "escodegen": "^2.0.0", "escope": "^3.6.0", "esprima": "^4.0.1", - "estraverse": "^4.3.0", - "globby": "^10.0.1", - "graceful-fs": "^4.2.2", - "jsdoc": "3.5.5", - "less-openui5": "^0.6.0", - "make-dir": "^3.0.0", + "estraverse": "5.1.0", + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "jsdoc": "^3.6.6", + "less-openui5": "^0.9.0", + "make-dir": "^3.1.0", "pretty-data": "^0.40.0", "pretty-hrtime": "^1.0.3", "replacestream": "^4.0.3", - "rimraf": "^3.0.0", - "semver": "^6.3.0", + "rimraf": "^3.0.2", + "semver": "^7.3.4", "slash": "^3.0.0", - "terser": "^4.3.8", - "xml2js": "^0.4.22", + "terser": "^5.5.1", + "xml2js": "^0.4.23", "yazl": "^2.5.1" }, "devDependencies": { - "ava": "^2.4.0", + "ava": "^3.13.0", "chai": "^4.1.2", "chai-fs": "^2.0.0", - "coveralls": "^3.0.7", - "cross-env": "^6.0.3", - "docdash": "^1.1.1", - "eslint": "^5.16.0", - "eslint-config-google": "^0.13.0", - "eslint-plugin-jsdoc": "^4.8.4", - "extract-zip": "^1.6.7", + "chokidar-cli": "^2.1.0", + "cross-env": "^7.0.3", + "depcheck": "^1.3.1", + "docdash": "^1.2.0", + "eslint": "^7.15.0", + "eslint-config-google": "^0.14.0", + "eslint-plugin-jsdoc": "^30.7.8", + "extract-zip": "^2.0.1", "mock-require": "^3.0.3", - "nyc": "^14.1.1", - "open-cli": "^5.0.0", + "nyc": "^15.1.0", + "open-cli": "^6.0.1", "recursive-readdir": "^2.1.1", - "sinon": "^7.5.0", + "sinon": "^9.2.1", "tap-nyan": "^1.1.0", "tap-xunit": "^2.4.1" } diff --git a/test/expected/build/application.a/dest-deps-excl/index.html b/test/expected/build/application.a/dest-deps-excl/index.html new file mode 100644 index 000000000..1523b1dc3 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/index.html @@ -0,0 +1,11 @@ + + + + Application A + + + + + + \ No newline at end of file diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/a/.library b/test/expected/build/application.a/dest-deps-excl/resources/library/a/.library new file mode 100644 index 000000000..cddfadd9a --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/a/.library @@ -0,0 +1,17 @@ + + + + library.a + SAP SE + Some fancy copyright ${currentYear} + 1.0.0 + + Library A + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library-RTL.css b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library-RTL.css new file mode 100644 index 000000000..5398b3f08 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library-RTL.css @@ -0,0 +1,3 @@ +.library-a-foo{color:#fafad2;padding:1px 4px 3px 2px} +/* Inline theming parameters */ +#sap-ui-theme-library\.a{background-image:url('data:text/plain;utf-8,%7B%22libraryAColor1%22%3A%22%23fafad2%22%7D')} diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library-parameters.json b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library-parameters.json new file mode 100644 index 000000000..da3b7a52f --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library-parameters.json @@ -0,0 +1 @@ +{"libraryAColor1":"#fafad2"} \ No newline at end of file diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library.css b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library.css new file mode 100644 index 000000000..ba056b3c0 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library.css @@ -0,0 +1,3 @@ +.library-a-foo{color:#fafad2;padding:1px 2px 3px 4px} +/* Inline theming parameters */ +#sap-ui-theme-library\.a{background-image:url('data:text/plain;utf-8,%7B%22libraryAColor1%22%3A%22%23fafad2%22%7D')} diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library.source.less b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library.source.less new file mode 100644 index 000000000..ff0f1d5e3 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/a/themes/base/library.source.less @@ -0,0 +1,6 @@ +@libraryAColor1: lightgoldenrodyellow; + +.library-a-foo { + color: @libraryAColor1; + padding: 1px 2px 3px 4px; +} diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/b/.library b/test/expected/build/application.a/dest-deps-excl/resources/library/b/.library new file mode 100644 index 000000000..8cfb124a9 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/b/.library @@ -0,0 +1,17 @@ + + + + library.b + SAP SE + Some fancy copyright ${currentYear} + 1.0.0 + + Library B + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-deps-excl/resources/library/c/.library b/test/expected/build/application.a/dest-deps-excl/resources/library/c/.library new file mode 100644 index 000000000..3c011ecd6 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/resources/library/c/.library @@ -0,0 +1,17 @@ + + + + library.c + SAP SE + ${copyright} + 1.0.0 + + Library C + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-deps-excl/test-dbg.js b/test/expected/build/application.a/dest-deps-excl/test-dbg.js new file mode 100644 index 000000000..cb4595405 --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/test-dbg.js @@ -0,0 +1,9 @@ +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/expected/build/application.a/dest-deps-excl/test-resources/LibraryC/Test.html b/test/expected/build/application.a/dest-deps-excl/test-resources/LibraryC/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps-excl/test-resources/library/a/Test.html b/test/expected/build/application.a/dest-deps-excl/test-resources/library/a/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps-excl/test-resources/library/b/Test.html b/test/expected/build/application.a/dest-deps-excl/test-resources/library/b/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps-excl/test.js b/test/expected/build/application.a/dest-deps-excl/test.js new file mode 100644 index 000000000..fd8278c6e --- /dev/null +++ b/test/expected/build/application.a/dest-deps-excl/test.js @@ -0,0 +1 @@ +sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); \ No newline at end of file diff --git a/test/expected/build/application.a/dest-deps/index.html b/test/expected/build/application.a/dest-deps/index.html new file mode 100644 index 000000000..1523b1dc3 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/index.html @@ -0,0 +1,11 @@ + + + + Application A + + + + + + \ No newline at end of file diff --git a/test/expected/build/application.a/dest-deps/resources/library/a/.library b/test/expected/build/application.a/dest-deps/resources/library/a/.library new file mode 100644 index 000000000..cddfadd9a --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/a/.library @@ -0,0 +1,17 @@ + + + + library.a + SAP SE + Some fancy copyright ${currentYear} + 1.0.0 + + Library A + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library-RTL.css b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library-RTL.css new file mode 100644 index 000000000..5398b3f08 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library-RTL.css @@ -0,0 +1,3 @@ +.library-a-foo{color:#fafad2;padding:1px 4px 3px 2px} +/* Inline theming parameters */ +#sap-ui-theme-library\.a{background-image:url('data:text/plain;utf-8,%7B%22libraryAColor1%22%3A%22%23fafad2%22%7D')} diff --git a/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library-parameters.json b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library-parameters.json new file mode 100644 index 000000000..da3b7a52f --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library-parameters.json @@ -0,0 +1 @@ +{"libraryAColor1":"#fafad2"} \ No newline at end of file diff --git a/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library.css b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library.css new file mode 100644 index 000000000..ba056b3c0 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library.css @@ -0,0 +1,3 @@ +.library-a-foo{color:#fafad2;padding:1px 2px 3px 4px} +/* Inline theming parameters */ +#sap-ui-theme-library\.a{background-image:url('data:text/plain;utf-8,%7B%22libraryAColor1%22%3A%22%23fafad2%22%7D')} diff --git a/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library.source.less b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library.source.less new file mode 100644 index 000000000..ff0f1d5e3 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/a/themes/base/library.source.less @@ -0,0 +1,6 @@ +@libraryAColor1: lightgoldenrodyellow; + +.library-a-foo { + color: @libraryAColor1; + padding: 1px 2px 3px 4px; +} diff --git a/test/expected/build/application.a/dest-deps/resources/library/b/.library b/test/expected/build/application.a/dest-deps/resources/library/b/.library new file mode 100644 index 000000000..8cfb124a9 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/b/.library @@ -0,0 +1,17 @@ + + + + library.b + SAP SE + Some fancy copyright ${currentYear} + 1.0.0 + + Library B + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-deps/resources/library/c/.library b/test/expected/build/application.a/dest-deps/resources/library/c/.library new file mode 100644 index 000000000..3c011ecd6 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/c/.library @@ -0,0 +1,17 @@ + + + + library.c + SAP SE + ${copyright} + 1.0.0 + + Library C + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-deps/resources/library/d/.library b/test/expected/build/application.a/dest-deps/resources/library/d/.library new file mode 100644 index 000000000..d6a612a92 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/d/.library @@ -0,0 +1,11 @@ + + + + library.d + SAP SE + Some fancy copyright + 1.0.0 + + Library D + + diff --git a/test/expected/build/application.a/dest-deps/resources/library/d/some-dbg.js b/test/expected/build/application.a/dest-deps/resources/library/d/some-dbg.js new file mode 100644 index 000000000..1e8c6a2f9 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/d/some-dbg.js @@ -0,0 +1,7 @@ +/*! + * Some fancy copyright + */ +(function() { + var someNonUglifiedVariable = "World"; + console.log('Hello ' + someNonUglifiedVariable); +})(); diff --git a/test/expected/build/application.a/dest-deps/resources/library/d/some.js b/test/expected/build/application.a/dest-deps/resources/library/d/some.js new file mode 100644 index 000000000..c23f5f207 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/library/d/some.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +(function(){var o="World";console.log("Hello "+o)})(); \ No newline at end of file diff --git a/test/expected/build/application.a/dest-deps/resources/ui5loader-dbg.js b/test/expected/build/application.a/dest-deps/resources/ui5loader-dbg.js new file mode 100644 index 000000000..0e76321fd --- /dev/null +++ b/test/expected/build/application.a/dest-deps/resources/ui5loader-dbg.js @@ -0,0 +1 @@ +// this is just a marker file to enable the EVO bundle format diff --git a/test/expected/build/application.a/dest-deps/resources/ui5loader.js b/test/expected/build/application.a/dest-deps/resources/ui5loader.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps/test-dbg.js b/test/expected/build/application.a/dest-deps/test-dbg.js new file mode 100644 index 000000000..cb4595405 --- /dev/null +++ b/test/expected/build/application.a/dest-deps/test-dbg.js @@ -0,0 +1,9 @@ +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/expected/build/application.a/dest-deps/test-resources/LibraryC/Test.html b/test/expected/build/application.a/dest-deps/test-resources/LibraryC/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps/test-resources/library/a/Test.html b/test/expected/build/application.a/dest-deps/test-resources/library/a/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps/test-resources/library/b/Test.html b/test/expected/build/application.a/dest-deps/test-resources/library/b/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps/test-resources/library/d/Test.html b/test/expected/build/application.a/dest-deps/test-resources/library/d/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-deps/test.js b/test/expected/build/application.a/dest-deps/test.js new file mode 100644 index 000000000..fd8278c6e --- /dev/null +++ b/test/expected/build/application.a/dest-deps/test.js @@ -0,0 +1 @@ +sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); \ No newline at end of file diff --git a/test/expected/build/application.a/dest-depself/index.html b/test/expected/build/application.a/dest-depself/index.html new file mode 100644 index 000000000..b0c4c25b7 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/index.html @@ -0,0 +1,11 @@ + + + + Application A + + + + + + \ No newline at end of file diff --git a/test/expected/build/application.a/dest-depself/resources/library/a/.library b/test/expected/build/application.a/dest-depself/resources/library/a/.library new file mode 100644 index 000000000..cddfadd9a --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/a/.library @@ -0,0 +1,17 @@ + + + + library.a + SAP SE + Some fancy copyright ${currentYear} + 1.0.0 + + Library A + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library-RTL.css b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library-RTL.css new file mode 100644 index 000000000..5398b3f08 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library-RTL.css @@ -0,0 +1,3 @@ +.library-a-foo{color:#fafad2;padding:1px 4px 3px 2px} +/* Inline theming parameters */ +#sap-ui-theme-library\.a{background-image:url('data:text/plain;utf-8,%7B%22libraryAColor1%22%3A%22%23fafad2%22%7D')} diff --git a/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library-parameters.json b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library-parameters.json new file mode 100644 index 000000000..da3b7a52f --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library-parameters.json @@ -0,0 +1 @@ +{"libraryAColor1":"#fafad2"} \ No newline at end of file diff --git a/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library.css b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library.css new file mode 100644 index 000000000..ba056b3c0 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library.css @@ -0,0 +1,3 @@ +.library-a-foo{color:#fafad2;padding:1px 2px 3px 4px} +/* Inline theming parameters */ +#sap-ui-theme-library\.a{background-image:url('data:text/plain;utf-8,%7B%22libraryAColor1%22%3A%22%23fafad2%22%7D')} diff --git a/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library.source.less b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library.source.less new file mode 100644 index 000000000..ff0f1d5e3 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/a/themes/base/library.source.less @@ -0,0 +1,6 @@ +@libraryAColor1: lightgoldenrodyellow; + +.library-a-foo { + color: @libraryAColor1; + padding: 1px 2px 3px 4px; +} diff --git a/test/expected/build/application.a/dest-depself/resources/library/b/.library b/test/expected/build/application.a/dest-depself/resources/library/b/.library new file mode 100644 index 000000000..8cfb124a9 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/b/.library @@ -0,0 +1,17 @@ + + + + library.b + SAP SE + Some fancy copyright ${currentYear} + 1.0.0 + + Library B + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-depself/resources/library/c/.library b/test/expected/build/application.a/dest-depself/resources/library/c/.library new file mode 100644 index 000000000..3c011ecd6 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/c/.library @@ -0,0 +1,17 @@ + + + + library.c + SAP SE + ${copyright} + 1.0.0 + + Library C + + + + library.d + + + + diff --git a/test/expected/build/application.a/dest-depself/resources/library/d/.library b/test/expected/build/application.a/dest-depself/resources/library/d/.library new file mode 100644 index 000000000..d6a612a92 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/d/.library @@ -0,0 +1,11 @@ + + + + library.d + SAP SE + Some fancy copyright + 1.0.0 + + Library D + + diff --git a/test/expected/build/application.a/dest-depself/resources/library/d/some-dbg.js b/test/expected/build/application.a/dest-depself/resources/library/d/some-dbg.js new file mode 100644 index 000000000..1e8c6a2f9 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/d/some-dbg.js @@ -0,0 +1,7 @@ +/*! + * Some fancy copyright + */ +(function() { + var someNonUglifiedVariable = "World"; + console.log('Hello ' + someNonUglifiedVariable); +})(); diff --git a/test/expected/build/application.a/dest-depself/resources/library/d/some.js b/test/expected/build/application.a/dest-depself/resources/library/d/some.js new file mode 100644 index 000000000..c23f5f207 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/library/d/some.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +(function(){var o="World";console.log("Hello "+o)})(); \ No newline at end of file diff --git a/test/expected/build/application.a/dest-depself/resources/sap-ui-custom-dbg.js b/test/expected/build/application.a/dest-depself/resources/sap-ui-custom-dbg.js new file mode 100644 index 000000000..456319972 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/sap-ui-custom-dbg.js @@ -0,0 +1 @@ +//@ui5-bundle sap-ui-custom-dbg.js diff --git a/test/expected/build/application.a/dest-depself/resources/sap-ui-custom.js b/test/expected/build/application.a/dest-depself/resources/sap-ui-custom.js new file mode 100644 index 000000000..c1aee5600 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/sap-ui-custom.js @@ -0,0 +1,10 @@ +//@ui5-bundle sap-ui-custom.js +sap.ui.require.preload({ + "application/a/test.js":function(){sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); +}, + "library/d/some.js":function(){/*! + * Some fancy copyright + */ +(function(){var o="World";console.log("Hello "+o)})(); +} +}); diff --git a/test/expected/build/application.a/dest-depself/resources/ui5loader-dbg.js b/test/expected/build/application.a/dest-depself/resources/ui5loader-dbg.js new file mode 100644 index 000000000..0e76321fd --- /dev/null +++ b/test/expected/build/application.a/dest-depself/resources/ui5loader-dbg.js @@ -0,0 +1 @@ +// this is just a marker file to enable the EVO bundle format diff --git a/test/expected/build/application.a/dest-depself/resources/ui5loader.js b/test/expected/build/application.a/dest-depself/resources/ui5loader.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-depself/test-dbg.js b/test/expected/build/application.a/dest-depself/test-dbg.js new file mode 100644 index 000000000..cb4595405 --- /dev/null +++ b/test/expected/build/application.a/dest-depself/test-dbg.js @@ -0,0 +1,9 @@ +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/expected/build/application.a/dest-depself/test-resources/LibraryC/Test.html b/test/expected/build/application.a/dest-depself/test-resources/LibraryC/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-depself/test-resources/library/a/Test.html b/test/expected/build/application.a/dest-depself/test-resources/library/a/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-depself/test-resources/library/b/Test.html b/test/expected/build/application.a/dest-depself/test-resources/library/b/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-depself/test-resources/library/d/Test.html b/test/expected/build/application.a/dest-depself/test-resources/library/d/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/application.a/dest-depself/test.js b/test/expected/build/application.a/dest-depself/test.js new file mode 100644 index 000000000..fd8278c6e --- /dev/null +++ b/test/expected/build/application.a/dest-depself/test.js @@ -0,0 +1 @@ +sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); \ No newline at end of file diff --git a/test/expected/build/application.a/dest-dev/index.html b/test/expected/build/application.a/dest-dev/index.html index 77b0207cc..1523b1dc3 100644 --- a/test/expected/build/application.a/dest-dev/index.html +++ b/test/expected/build/application.a/dest-dev/index.html @@ -2,6 +2,8 @@ Application A + diff --git a/test/expected/build/application.a/dest-dev/test.js b/test/expected/build/application.a/dest-dev/test.js index a3df410c3..cb4595405 100644 --- a/test/expected/build/application.a/dest-dev/test.js +++ b/test/expected/build/application.a/dest-dev/test.js @@ -1,5 +1,9 @@ -function test(paramA) { - var variableA = paramA; - console.log(variableA); -} -test(); +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/expected/build/application.a/dest-self/index.html b/test/expected/build/application.a/dest-self/index.html new file mode 100644 index 000000000..b0c4c25b7 --- /dev/null +++ b/test/expected/build/application.a/dest-self/index.html @@ -0,0 +1,11 @@ + + + + Application A + + + + + + \ No newline at end of file diff --git a/test/expected/build/application.a/dest-self/resources/sap-ui-custom-dbg.js b/test/expected/build/application.a/dest-self/resources/sap-ui-custom-dbg.js new file mode 100644 index 000000000..456319972 --- /dev/null +++ b/test/expected/build/application.a/dest-self/resources/sap-ui-custom-dbg.js @@ -0,0 +1 @@ +//@ui5-bundle sap-ui-custom-dbg.js diff --git a/test/expected/build/application.a/dest-self/resources/sap-ui-custom.js b/test/expected/build/application.a/dest-self/resources/sap-ui-custom.js new file mode 100644 index 000000000..7728d6932 --- /dev/null +++ b/test/expected/build/application.a/dest-self/resources/sap-ui-custom.js @@ -0,0 +1,10 @@ +//@ui5-bundle sap-ui-custom.js +sap.ui.require.preload({ + "application/a/test.js":function(){sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); +}, + "library/d/some.js":function(){/*! + * ${copyright} + */ +(function(){var o="World";console.log("Hello "+o)})(); +} +}); diff --git a/test/expected/build/application.a/dest-self/test-dbg.js b/test/expected/build/application.a/dest-self/test-dbg.js new file mode 100644 index 000000000..cb4595405 --- /dev/null +++ b/test/expected/build/application.a/dest-self/test-dbg.js @@ -0,0 +1,9 @@ +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/expected/build/application.a/dest-self/test.js b/test/expected/build/application.a/dest-self/test.js new file mode 100644 index 000000000..fd8278c6e --- /dev/null +++ b/test/expected/build/application.a/dest-self/test.js @@ -0,0 +1 @@ +sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); \ No newline at end of file diff --git a/test/expected/build/application.a/dest/index.html b/test/expected/build/application.a/dest/index.html index 77b0207cc..1523b1dc3 100644 --- a/test/expected/build/application.a/dest/index.html +++ b/test/expected/build/application.a/dest/index.html @@ -2,6 +2,8 @@ Application A + diff --git a/test/expected/build/application.a/dest/test-dbg.js b/test/expected/build/application.a/dest/test-dbg.js index a3df410c3..cb4595405 100644 --- a/test/expected/build/application.a/dest/test-dbg.js +++ b/test/expected/build/application.a/dest/test-dbg.js @@ -1,5 +1,9 @@ -function test(paramA) { - var variableA = paramA; - console.log(variableA); -} -test(); +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/expected/build/application.a/dest/test.js b/test/expected/build/application.a/dest/test.js index 387af3930..fd8278c6e 100644 --- a/test/expected/build/application.a/dest/test.js +++ b/test/expected/build/application.a/dest/test.js @@ -1 +1 @@ -function test(t){var o=t;console.log(o)}test(); \ No newline at end of file +sap.ui.define(["library/d/some"],function(n){function o(n){var o=n;console.log(o)}o()}); \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/Component-preload.js b/test/expected/build/application.j/dest-resources-json/Component-preload.js new file mode 100644 index 000000000..4e58fdf09 --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/Component-preload.js @@ -0,0 +1,12 @@ +//@ui5-bundle application/j/Component-preload.js +jQuery.sap.registerPreloadedModules({ +"version":"2.0", +"modules":{ + "application/j/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.j.Component",{metadata:{manifest:"json"}})}); +}, + "application/j/changes/coding/MyExtension.js":function(){sap.ui.define([],function(){return{}}); +}, + "application/j/changes/flexibility-bundle.json":'{"changes":[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"compVariants":[{"fileName":"id_111_compVariants","fileType":"variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"appDescriptorChange":false}],"variants":[{"fileName":"id_111_test","fileType":"ctrl_variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantDependentControlChanges":[{"fileName":"id_111_variantDependentControlChange","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"variantReference":"someting here"}],"variantManagementChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_management_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]}', + "application/j/changes/fragments/MyFragment.fragment.xml":'', + "application/j/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"minUI5Version":"1.73.2","libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}}' +}}); diff --git a/test/expected/build/application.j/dest-resources-json/Component.js b/test/expected/build/application.j/dest-resources-json/Component.js new file mode 100644 index 000000000..984f96eaf --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/Component.js @@ -0,0 +1 @@ +sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.j.Component",{metadata:{manifest:"json"}})}); \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/changes/coding/MyExtension.js b/test/expected/build/application.j/dest-resources-json/changes/coding/MyExtension.js new file mode 100644 index 000000000..b9e475d8e --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/changes/coding/MyExtension.js @@ -0,0 +1 @@ +sap.ui.define([],function(){return{}}); \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/changes/flexibility-bundle.json b/test/expected/build/application.j/dest-resources-json/changes/flexibility-bundle.json new file mode 100644 index 000000000..b3a5c5b1e --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/changes/flexibility-bundle.json @@ -0,0 +1 @@ +{"changes":[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"compVariants":[{"fileName":"id_111_compVariants","fileType":"variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"appDescriptorChange":false}],"variants":[{"fileName":"id_111_test","fileType":"ctrl_variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantDependentControlChanges":[{"fileName":"id_111_variantDependentControlChange","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"variantReference":"someting here"}],"variantManagementChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_management_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]} \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/changes/fragments/MyFragment.fragment.xml b/test/expected/build/application.j/dest-resources-json/changes/fragments/MyFragment.fragment.xml new file mode 100644 index 000000000..39ce6859b --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/changes/fragments/MyFragment.fragment.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/manifest.json b/test/expected/build/application.j/dest-resources-json/manifest.json new file mode 100644 index 000000000..f82703903 --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/manifest.json @@ -0,0 +1,28 @@ +{ + "_version": "1.1.0", + "sap.app": { + "_version": "1.1.0", + "id": "application.j", + "type": "application", + "applicationVersion": { + "version": "1.2.2" + }, + "embeds": [ + "embedded" + ], + "title": "{{title}}" + }, + "sap.ui5": { + "dependencies": { + "minUI5Version": "1.73.2", + "libs": { + "sap.ui.layout": {}, + "sap.ui.core": {}, + "sap.m": {}, + "sap.ui.fl": { + "lazy": false + } + } + } + } +} \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/resources.json b/test/expected/build/application.j/dest-resources-json/resources.json new file mode 100644 index 000000000..6cc8eb8a7 --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/resources.json @@ -0,0 +1,86 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": "Component-preload.js", + "module": "application/j/Component-preload.js", + "size": 3746, + "merged": true, + "included": [ + "application/j/Component.js", + "application/j/changes/coding/MyExtension.js", + "application/j/changes/flexibility-bundle.json", + "application/j/changes/fragments/MyFragment.fragment.xml", + "application/j/manifest.json" + ] + }, + { + "name": "Component.js", + "module": "application/j/Component.js", + "size": 141, + "required": [ + "sap/m/library.js", + "sap/ui/core/UIComponent.js", + "sap/ui/core/library.js", + "sap/ui/fl/library.js", + "sap/ui/layout/library.js" + ] + }, + { + "name": "changes/coding/MyExtension.js", + "module": "application/j/changes/coding/MyExtension.js", + "size": 39 + }, + { + "name": "changes/flexibility-bundle.json", + "module": "application/j/changes/flexibility-bundle.json", + "size": 2864 + }, + { + "name": "changes/fragments/MyFragment.fragment.xml", + "module": "application/j/changes/fragments/MyFragment.fragment.xml", + "size": 13 + }, + { + "name": "changes/id_111_appDescriptor.change", + "size": 464 + }, + { + "name": "changes/id_111_compVariants.variant", + "size": 466 + }, + { + "name": "changes/id_111_test.ctrl_variant", + "size": 432 + }, + { + "name": "changes/id_111_test.ctrl_variant_change", + "size": 439 + }, + { + "name": "changes/id_111_test.ctrl_variant_management_change", + "size": 450 + }, + { + "name": "changes/id_111_variantDependentControlChange.change", + "size": 489 + }, + { + "name": "changes/id_123_addField.change", + "size": 430 + }, + { + "name": "changes/id_456_addField.change", + "size": 430 + }, + { + "name": "manifest.json", + "module": "application/j/manifest.json", + "size": 423 + }, + { + "name": "resources.json", + "size": 1870 + } + ] +} \ No newline at end of file diff --git a/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json b/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json new file mode 100644 index 000000000..551fc7d92 --- /dev/null +++ b/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json @@ -0,0 +1,7 @@ +{ + "name": "application.j", + "version": "1.0.0", + "buildTimestamp": "202008120917", + "scmRevision": "", + "libraries": [] +} \ No newline at end of file diff --git a/test/expected/build/application.j/dest/Component-preload.js b/test/expected/build/application.j/dest/Component-preload.js index 8b4bc76e1..4e58fdf09 100644 --- a/test/expected/build/application.j/dest/Component-preload.js +++ b/test/expected/build/application.j/dest/Component-preload.js @@ -4,9 +4,9 @@ jQuery.sap.registerPreloadedModules({ "modules":{ "application/j/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.j.Component",{metadata:{manifest:"json"}})}); }, - "application/j/changes/changes-bundle.json":'[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]', "application/j/changes/coding/MyExtension.js":function(){sap.ui.define([],function(){return{}}); }, + "application/j/changes/flexibility-bundle.json":'{"changes":[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"compVariants":[{"fileName":"id_111_compVariants","fileType":"variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"appDescriptorChange":false}],"variants":[{"fileName":"id_111_test","fileType":"ctrl_variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantDependentControlChanges":[{"fileName":"id_111_variantDependentControlChange","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"variantReference":"someting here"}],"variantManagementChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_management_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]}', "application/j/changes/fragments/MyFragment.fragment.xml":'', - "application/j/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}}' + "application/j/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"minUI5Version":"1.73.2","libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}}' }}); diff --git a/test/expected/build/application.j/dest/changes/changes-bundle.json b/test/expected/build/application.j/dest/changes/changes-bundle.json deleted file mode 100644 index 0e270c459..000000000 --- a/test/expected/build/application.j/dest/changes/changes-bundle.json +++ /dev/null @@ -1 +0,0 @@ -[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}] \ No newline at end of file diff --git a/test/expected/build/application.j/dest/changes/flexibility-bundle.json b/test/expected/build/application.j/dest/changes/flexibility-bundle.json new file mode 100644 index 000000000..b3a5c5b1e --- /dev/null +++ b/test/expected/build/application.j/dest/changes/flexibility-bundle.json @@ -0,0 +1 @@ +{"changes":[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"compVariants":[{"fileName":"id_111_compVariants","fileType":"variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"appDescriptorChange":false}],"variants":[{"fileName":"id_111_test","fileType":"ctrl_variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantDependentControlChanges":[{"fileName":"id_111_variantDependentControlChange","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"variantReference":"someting here"}],"variantManagementChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_management_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]} \ No newline at end of file diff --git a/test/expected/build/application.j/dest/manifest.json b/test/expected/build/application.j/dest/manifest.json index eb1a2c611..f82703903 100644 --- a/test/expected/build/application.j/dest/manifest.json +++ b/test/expected/build/application.j/dest/manifest.json @@ -14,6 +14,7 @@ }, "sap.ui5": { "dependencies": { + "minUI5Version": "1.73.2", "libs": { "sap.ui.layout": {}, "sap.ui.core": {}, diff --git a/test/expected/build/library.d/dest/resources/library/d/some-dbg.js b/test/expected/build/library.d/dest/resources/library/d/some-dbg.js index cb7722a38..1e8c6a2f9 100644 --- a/test/expected/build/library.d/dest/resources/library/d/some-dbg.js +++ b/test/expected/build/library.d/dest/resources/library/d/some-dbg.js @@ -1,4 +1,7 @@ /*! * Some fancy copyright */ -console.log('HelloWorld'); \ No newline at end of file +(function() { + var someNonUglifiedVariable = "World"; + console.log('Hello ' + someNonUglifiedVariable); +})(); diff --git a/test/expected/build/library.d/dest/resources/library/d/some.js b/test/expected/build/library.d/dest/resources/library/d/some.js index a5504d866..c23f5f207 100644 --- a/test/expected/build/library.d/dest/resources/library/d/some.js +++ b/test/expected/build/library.d/dest/resources/library/d/some.js @@ -1,4 +1,4 @@ /*! * Some fancy copyright */ -console.log("HelloWorld"); \ No newline at end of file +(function(){var o="World";console.log("Hello "+o)})(); \ No newline at end of file diff --git a/test/expected/build/library.d/preload/resources/library/d/library-preload.js b/test/expected/build/library.d/preload/resources/library/d/library-preload.js index 807feb583..3a8e66b86 100644 --- a/test/expected/build/library.d/preload/resources/library/d/library-preload.js +++ b/test/expected/build/library.d/preload/resources/library/d/library-preload.js @@ -5,6 +5,6 @@ jQuery.sap.registerPreloadedModules({ "library/d/some.js":function(){/*! * ${copyright} */ -console.log("HelloWorld"); +(function(){var o="World";console.log("Hello "+o)})(); } }}); diff --git a/test/expected/build/library.d/preload/resources/library/d/some.js b/test/expected/build/library.d/preload/resources/library/d/some.js index 81e734360..fa1d786f7 100644 --- a/test/expected/build/library.d/preload/resources/library/d/some.js +++ b/test/expected/build/library.d/preload/resources/library/d/some.js @@ -1,4 +1,7 @@ /*! * ${copyright} */ -console.log('HelloWorld'); \ No newline at end of file +(function() { + var someNonUglifiedVariable = "World"; + console.log('Hello ' + someNonUglifiedVariable); +})(); diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/.library b/test/expected/build/library.h/dest-resources-json/resources/library/h/.library new file mode 100644 index 000000000..9084728e8 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/.library @@ -0,0 +1,19 @@ + + + + library.h + SAP SE + Some fancy copyright + 1.0.0 + + Library H + + + + + + + + + + diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/Component-preload.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/Component-preload.js new file mode 100644 index 000000000..f66daec7d --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/Component-preload.js @@ -0,0 +1,10 @@ +//@ui5-bundle library/h/components/Component-preload.js +sap.ui.require.preload({ + "library/h/components/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); +}, + "library/h/components/TodoComponent.js":function(){/*! + * Some fancy copyright + */ +console.log(" File "); +} +}); diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/Component.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/Component.js new file mode 100644 index 000000000..422a97071 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/Component.js @@ -0,0 +1 @@ +sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/TodoComponent.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/TodoComponent.js new file mode 100644 index 000000000..bcf866e67 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/TodoComponent.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +console.log(" File "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/resources.json b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/resources.json new file mode 100644 index 000000000..a1dda2e2d --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/resources.json @@ -0,0 +1,84 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": "Component-preload.js", + "module": "library/h/components/Component-preload.js", + "size": 361, + "merged": true, + "included": [ + "library/h/components/Component.js", + "library/h/components/TodoComponent.js" + ] + }, + { + "name": "Component.js", + "module": "library/h/components/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "TodoComponent.js", + "module": "library/h/components/TodoComponent.js", + "size": 54, + "format": "raw" + }, + { + "name": "resources.json", + "size": 1904 + }, + { + "name": "subcomponent1/Component-preload.js", + "module": "library/h/components/subcomponent1/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent1/Component.js" + ] + }, + { + "name": "subcomponent1/Component.js", + "module": "library/h/components/subcomponent1/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "subcomponent2/Component-preload.js", + "module": "library/h/components/subcomponent2/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent2/Component.js" + ] + }, + { + "name": "subcomponent2/Component.js", + "module": "library/h/components/subcomponent2/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "subcomponent3/Component-preload.js", + "module": "library/h/components/subcomponent3/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent3/Component.js" + ] + }, + { + "name": "subcomponent3/Component.js", + "module": "library/h/components/subcomponent3/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + } + ] +} \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/Component-preload.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/Component-preload.js new file mode 100644 index 000000000..d2309dcdf --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/Component-preload.js @@ -0,0 +1,5 @@ +//@ui5-bundle library/h/components/subcomponent1/Component-preload.js +sap.ui.require.preload({ + "library/h/components/subcomponent1/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); +} +}); diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/Component.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/Component.js new file mode 100644 index 000000000..422a97071 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/Component.js @@ -0,0 +1 @@ +sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/resources.json b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/resources.json new file mode 100644 index 000000000..5de7b8334 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent1/resources.json @@ -0,0 +1,26 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": "Component-preload.js", + "module": "library/h/components/subcomponent1/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent1/Component.js" + ] + }, + { + "name": "Component.js", + "module": "library/h/components/subcomponent1/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "resources.json", + "size": 494 + } + ] +} \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/Component-preload.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/Component-preload.js new file mode 100644 index 000000000..ce88226b9 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/Component-preload.js @@ -0,0 +1,5 @@ +//@ui5-bundle library/h/components/subcomponent2/Component-preload.js +sap.ui.require.preload({ + "library/h/components/subcomponent2/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); +} +}); diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/Component.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/Component.js new file mode 100644 index 000000000..422a97071 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/Component.js @@ -0,0 +1 @@ +sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/resources.json b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/resources.json new file mode 100644 index 000000000..ba1172a4c --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent2/resources.json @@ -0,0 +1,26 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": "Component-preload.js", + "module": "library/h/components/subcomponent2/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent2/Component.js" + ] + }, + { + "name": "Component.js", + "module": "library/h/components/subcomponent2/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "resources.json", + "size": 494 + } + ] +} \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/Component-preload.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/Component-preload.js new file mode 100644 index 000000000..4b88fc476 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/Component-preload.js @@ -0,0 +1,5 @@ +//@ui5-bundle library/h/components/subcomponent3/Component-preload.js +sap.ui.require.preload({ + "library/h/components/subcomponent3/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); +} +}); diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/Component.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/Component.js new file mode 100644 index 000000000..422a97071 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/Component.js @@ -0,0 +1 @@ +sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{})}); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/resources.json b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/resources.json new file mode 100644 index 000000000..b24c48464 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/components/subcomponent3/resources.json @@ -0,0 +1,26 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": "Component-preload.js", + "module": "library/h/components/subcomponent3/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent3/Component.js" + ] + }, + { + "name": "Component.js", + "module": "library/h/components/subcomponent3/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "resources.json", + "size": 494 + } + ] +} \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/customBundle.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/customBundle.js new file mode 100644 index 000000000..e9e0e00ed --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/customBundle.js @@ -0,0 +1,24 @@ +//@ui5-bundle library/h/customBundle.js +sap.ui.require.preload({ + "library/h/file.js":function(){/*! + * Some fancy copyright + */ +console.log(" File "); +}, + "library/h/library.js":function(){/*! + * Some fancy copyright + */ +console.log(" Library "); +}, + "library/h/some.js":function(){/*! + * Some fancy copyright + */ +//@ui5-bundle-raw-include library/h/other.js +console.log(" Some "); +} +}); +//@ui5-bundle-raw-include library/h/not.js +/*! + * Some fancy copyright + */ +console.log(" Not including "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/designtime/library.designtime.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/designtime/library.designtime.js new file mode 100644 index 000000000..9b135171d --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/designtime/library.designtime.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +var myexport=function(){"use strict";String("asd")}(); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/file.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/file.js new file mode 100644 index 000000000..bcf866e67 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/file.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +console.log(" File "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/i18n/messagebundle.properties b/test/expected/build/library.h/dest-resources-json/resources/library/h/i18n/messagebundle.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/i18n/messagebundle.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/i18n/messagebundle_en.properties b/test/expected/build/library.h/dest-resources-json/resources/library/h/i18n/messagebundle_en.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/i18n/messagebundle_en.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/library.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/library.js new file mode 100644 index 000000000..6900e2218 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/library.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +console.log(" Library "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/manifest.json b/test/expected/build/library.h/dest-resources-json/resources/library/h/manifest.json new file mode 100644 index 000000000..de1590b80 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/manifest.json @@ -0,0 +1,34 @@ +{ + "_version": "1.9.0", + "sap.app": { + "id": "library.h", + "type": "library", + "embeds": [], + "applicationVersion": { + "version": "1.0.0" + }, + "title": "Library H", + "description": "Library H", + "resources": "resources.json", + "offline": true + }, + "sap.ui": { + "technology": "UI5", + "supportedThemes": [] + }, + "sap.ui5": { + "dependencies": { + "minUI5Version": "1.0", + "libs": {} + }, + "library": { + "i18n": false, + "content": { + "controls": [], + "elements": [], + "types": [], + "interfaces": [] + } + } + } +} \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/not.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/not.js new file mode 100644 index 000000000..c249a10c8 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/not.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +console.log(" Not including "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/resources.json b/test/expected/build/library.h/dest-resources-json/resources/library/h/resources.json new file mode 100644 index 000000000..f3e80a739 --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/resources.json @@ -0,0 +1,159 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": ".library", + "size": 473 + }, + { + "name": "components/Component-preload.js", + "module": "library/h/components/Component-preload.js", + "size": 361, + "merged": true, + "included": [ + "library/h/components/Component.js", + "library/h/components/TodoComponent.js" + ] + }, + { + "name": "components/Component.js", + "module": "library/h/components/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "components/TodoComponent.js", + "module": "library/h/components/TodoComponent.js", + "size": 54, + "format": "raw" + }, + { + "name": "components/subcomponent1/Component-preload.js", + "module": "library/h/components/subcomponent1/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent1/Component.js" + ] + }, + { + "name": "components/subcomponent1/Component.js", + "module": "library/h/components/subcomponent1/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "components/subcomponent2/Component-preload.js", + "module": "library/h/components/subcomponent2/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent2/Component.js" + ] + }, + { + "name": "components/subcomponent2/Component.js", + "module": "library/h/components/subcomponent2/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "components/subcomponent3/Component-preload.js", + "module": "library/h/components/subcomponent3/Component-preload.js", + "size": 279, + "merged": true, + "included": [ + "library/h/components/subcomponent3/Component.js" + ] + }, + { + "name": "components/subcomponent3/Component.js", + "module": "library/h/components/subcomponent3/Component.js", + "size": 115, + "required": [ + "sap/ui/core/UIComponent.js" + ] + }, + { + "name": "customBundle.js", + "module": "library/h/customBundle.js", + "size": 495, + "merged": true, + "included": [ + "library/h/file.js", + "library/h/library.js", + "library/h/some.js", + "library/h/other.js", + "library/h/not.js" + ] + }, + { + "name": "designtime/library.designtime.js", + "module": "library/h/designtime/library.designtime.js", + "size": 86, + "requiresTopLevelScope": true, + "exposedGlobalNames": [ + "myexport" + ], + "format": "raw", + "designtime": true + }, + { + "name": "file.js", + "module": "library/h/file.js", + "size": 54, + "format": "raw" + }, + { + "name": "i18n/messagebundle.properties", + "module": "library/h/i18n/messagebundle.properties", + "size": 3, + "locale": "", + "raw": "i18n/messagebundle.properties" + }, + { + "name": "i18n/messagebundle_en.properties", + "module": "library/h/i18n/messagebundle_en.properties", + "size": 3, + "locale": "en", + "raw": "i18n/messagebundle.properties" + }, + { + "name": "library.js", + "module": "library/h/library.js", + "size": 57, + "format": "raw" + }, + { + "name": "manifest.json", + "module": "library/h/manifest.json", + "size": 613 + }, + { + "name": "not.js", + "module": "library/h/not.js", + "size": 63, + "format": "raw" + }, + { + "name": "resources.json", + "size": 3500 + }, + { + "name": "some.js", + "module": "library/h/some.js", + "size": 99, + "format": "raw", + "merged": true, + "included": [ + "library/h/other.js" + ] + } + ] +} \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/resources/library/h/some.js b/test/expected/build/library.h/dest-resources-json/resources/library/h/some.js new file mode 100644 index 000000000..1e86f9afc --- /dev/null +++ b/test/expected/build/library.h/dest-resources-json/resources/library/h/some.js @@ -0,0 +1,5 @@ +/*! + * Some fancy copyright + */ +//@ui5-bundle-raw-include library/h/other.js +console.log(" Some "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest-resources-json/test-resources/library/d/Test.html b/test/expected/build/library.h/dest-resources-json/test-resources/library/d/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected/build/library.h/dest/resources/library/h/.library b/test/expected/build/library.h/dest/resources/library/h/.library index 2b110f205..9084728e8 100644 --- a/test/expected/build/library.h/dest/resources/library/h/.library +++ b/test/expected/build/library.h/dest/resources/library/h/.library @@ -6,6 +6,14 @@ Some fancy copyright 1.0.0 - Library D + Library H + + + + + + + + diff --git a/test/expected/build/library.h/dest/resources/library/h/customBundle.js b/test/expected/build/library.h/dest/resources/library/h/customBundle.js index 21db087bb..e9e0e00ed 100644 --- a/test/expected/build/library.h/dest/resources/library/h/customBundle.js +++ b/test/expected/build/library.h/dest/resources/library/h/customBundle.js @@ -13,6 +13,12 @@ console.log(" Library "); "library/h/some.js":function(){/*! * Some fancy copyright */ +//@ui5-bundle-raw-include library/h/other.js console.log(" Some "); } }); +//@ui5-bundle-raw-include library/h/not.js +/*! + * Some fancy copyright + */ +console.log(" Not including "); \ No newline at end of file diff --git a/test/expected/build/library.h/dest/resources/library/h/designtime/library.designtime.js b/test/expected/build/library.h/dest/resources/library/h/designtime/library.designtime.js new file mode 100644 index 000000000..9b135171d --- /dev/null +++ b/test/expected/build/library.h/dest/resources/library/h/designtime/library.designtime.js @@ -0,0 +1,4 @@ +/*! + * Some fancy copyright + */ +var myexport=function(){"use strict";String("asd")}(); \ No newline at end of file diff --git a/test/expected/build/library.h/dest/resources/library/h/i18n/messagebundle.properties b/test/expected/build/library.h/dest/resources/library/h/i18n/messagebundle.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/test/expected/build/library.h/dest/resources/library/h/i18n/messagebundle.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/test/expected/build/library.h/dest/resources/library/h/i18n/messagebundle_en.properties b/test/expected/build/library.h/dest/resources/library/h/i18n/messagebundle_en.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/test/expected/build/library.h/dest/resources/library/h/i18n/messagebundle_en.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/test/expected/build/library.h/dest/resources/library/h/manifest.json b/test/expected/build/library.h/dest/resources/library/h/manifest.json index 2e67ab58d..de1590b80 100644 --- a/test/expected/build/library.h/dest/resources/library/h/manifest.json +++ b/test/expected/build/library.h/dest/resources/library/h/manifest.json @@ -3,17 +3,12 @@ "sap.app": { "id": "library.h", "type": "library", - "embeds": [ - "components", - "components/subcomponent1", - "components/subcomponent2", - "components/subcomponent3" - ], + "embeds": [], "applicationVersion": { "version": "1.0.0" }, - "title": "Library D", - "description": "Library D", + "title": "Library H", + "description": "Library H", "resources": "resources.json", "offline": true }, diff --git a/test/expected/build/library.h/dest/resources/library/h/some.js b/test/expected/build/library.h/dest/resources/library/h/some.js index 98e1e6665..1e86f9afc 100644 --- a/test/expected/build/library.h/dest/resources/library/h/some.js +++ b/test/expected/build/library.h/dest/resources/library/h/some.js @@ -1,4 +1,5 @@ /*! * Some fancy copyright */ +//@ui5-bundle-raw-include library/h/other.js console.log(" Some "); \ No newline at end of file diff --git a/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/.library b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/.library index 7efee8324..9089c4f9b 100644 --- a/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/.library +++ b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/.library @@ -8,4 +8,13 @@ Core + + + + + + + + diff --git a/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-preload.js b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-preload.js index dbdb964c1..5f9e0796e 100644 --- a/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-preload.js +++ b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-preload.js @@ -2,6 +2,9 @@ jQuery.sap.registerPreloadedModules({ "version":"2.0", "modules":{ + "sap/ui/core/one.js":function(){function One(){return 1} +this.One=One; +}, "sap/ui/core/some.js":function(){/*! * ${copyright} */ diff --git a/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/one.js b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/one.js new file mode 100644 index 000000000..753bd0523 --- /dev/null +++ b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/one.js @@ -0,0 +1,3 @@ +function One(){ + return 1; +} diff --git a/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/Button.less b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/Button.less new file mode 100644 index 000000000..ca968183f --- /dev/null +++ b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/Button.less @@ -0,0 +1,3 @@ +.someClass { + color: @someColor +} diff --git a/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library-RTL.css b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library-RTL.css new file mode 100644 index 000000000..5009ca50e --- /dev/null +++ b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library-RTL.css @@ -0,0 +1,3 @@ +.someClass{color:#000} +/* Inline theming parameters */ +#sap-ui-theme-theme\.j{background-image:url('data:text/plain;utf-8,%7B%22someColor%22%3A%22%23000%22%7D')} diff --git a/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library-parameters.json b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library-parameters.json new file mode 100644 index 000000000..a190cda03 --- /dev/null +++ b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library-parameters.json @@ -0,0 +1 @@ +{"someColor":"#000"} \ No newline at end of file diff --git a/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library.css b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library.css new file mode 100644 index 000000000..5009ca50e --- /dev/null +++ b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library.css @@ -0,0 +1,3 @@ +.someClass{color:#000} +/* Inline theming parameters */ +#sap-ui-theme-theme\.j{background-image:url('data:text/plain;utf-8,%7B%22someColor%22%3A%22%23000%22%7D')} diff --git a/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library.source.less b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library.source.less new file mode 100644 index 000000000..834de919e --- /dev/null +++ b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/library.source.less @@ -0,0 +1,2 @@ +@someColor: black; +@import "Button.less"; diff --git a/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/resources.json b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/resources.json new file mode 100644 index 000000000..d4c81a925 --- /dev/null +++ b/test/expected/build/theme.j/dest-resources-json/resources/theme/j/themes/somefancytheme/resources.json @@ -0,0 +1,37 @@ +{ + "_version": "1.1.0", + "resources": [ + { + "name": "Button.less", + "size": 34, + "designtime": true, + "theme": "somefancytheme" + }, + { + "name": "library-RTL.css", + "size": 162, + "theme": "somefancytheme" + }, + { + "name": "library-parameters.json", + "module": "theme/j/themes/somefancytheme/library-parameters.json", + "size": 20, + "theme": "somefancytheme" + }, + { + "name": "library.css", + "size": 162, + "theme": "somefancytheme" + }, + { + "name": "library.source.less", + "size": 42, + "designtime": true, + "theme": "somefancytheme" + }, + { + "name": "resources.json", + "size": 633 + } + ] +} \ No newline at end of file diff --git a/test/fixtures/application.a/webapp/index.html b/test/fixtures/application.a/webapp/index.html index 77b0207cc..1523b1dc3 100644 --- a/test/fixtures/application.a/webapp/index.html +++ b/test/fixtures/application.a/webapp/index.html @@ -2,6 +2,8 @@ Application A + diff --git a/test/fixtures/application.a/webapp/test.js b/test/fixtures/application.a/webapp/test.js index a3df410c3..cb4595405 100644 --- a/test/fixtures/application.a/webapp/test.js +++ b/test/fixtures/application.a/webapp/test.js @@ -1,5 +1,9 @@ -function test(paramA) { - var variableA = paramA; - console.log(variableA); -} -test(); +sap.ui.define([ + "library/d/some" +], function(someObject) { + function test(paramA) { + var variableA = paramA; + console.log(variableA); + } + test(); +}); diff --git a/test/fixtures/application.h/ui5.yaml b/test/fixtures/application.h/ui5.yaml index 07bdb70d7..9365040dc 100644 --- a/test/fixtures/application.h/ui5.yaml +++ b/test/fixtures/application.h/ui5.yaml @@ -1,5 +1,5 @@ --- -specVersion: "0.1" +specVersion: "2.0" type: application metadata: name: application.h diff --git a/test/expected/build/application.j/dest/changes/id_456_addField.change b/test/fixtures/application.j/webapp/changes/id_111_appDescriptor.change similarity index 75% rename from test/expected/build/application.j/dest/changes/id_456_addField.change rename to test/fixtures/application.j/webapp/changes/id_111_appDescriptor.change index 4d4c73b51..9c7f911b9 100644 --- a/test/expected/build/application.j/dest/changes/id_456_addField.change +++ b/test/fixtures/application.j/webapp/changes/id_111_appDescriptor.change @@ -1,5 +1,5 @@ { - "fileName": "id_456_addField", + "fileName": "id_111_compVariants", "fileType": "change", "changeType": "hideControl", "component": "application.j.Component", @@ -10,11 +10,12 @@ "layer": "VENDOR", "texts": {}, "namespace": "apps/application.j.Component/changes", - "creation": "2023-10-30T13:52:40.4754350Z", + "creation": "2025-10-30T13:52:40.4754350Z", "originalLanguage": "", "conditions": {}, "support": { "generator": "did it", "user": "Max Mustermann" - } + }, + "appDescriptorChange": true } diff --git a/test/fixtures/application.j/webapp/changes/id_111_compVariants.variant b/test/fixtures/application.j/webapp/changes/id_111_compVariants.variant new file mode 100644 index 000000000..26431d338 --- /dev/null +++ b/test/fixtures/application.j/webapp/changes/id_111_compVariants.variant @@ -0,0 +1,21 @@ +{ + "fileName": "id_111_compVariants", + "fileType": "variant", + "changeType": "hideControl", + "component": "application.j.Component", + "content": {}, + "selector": { + "id": "control1" + }, + "layer": "VENDOR", + "texts": {}, + "namespace": "apps/application.j.Component/changes", + "creation": "2025-10-30T13:52:40.4754350Z", + "originalLanguage": "", + "conditions": {}, + "support": { + "generator": "did it", + "user": "Max Mustermann" + }, + "appDescriptorChange": false +} diff --git a/test/expected/build/application.j/dest/changes/id_123_addField.change b/test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant similarity index 86% rename from test/expected/build/application.j/dest/changes/id_123_addField.change rename to test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant index 41d9bb61c..01d2bfb47 100644 --- a/test/expected/build/application.j/dest/changes/id_123_addField.change +++ b/test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant @@ -1,6 +1,6 @@ { - "fileName": "id_123_addField", - "fileType": "change", + "fileName": "id_111_test", + "fileType": "ctrl_variant", "changeType": "hideControl", "component": "application.j.Component", "content": {}, diff --git a/test/expected/build/application.i/dest/changes/id_123_addField.change b/test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant_change similarity index 63% rename from test/expected/build/application.i/dest/changes/id_123_addField.change rename to test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant_change index b1b1e9cda..8691c2e82 100644 --- a/test/expected/build/application.i/dest/changes/id_123_addField.change +++ b/test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant_change @@ -1,15 +1,15 @@ { - "fileName": "id_123_addField", - "fileType": "change", + "fileName": "id_111_test", + "fileType": "ctrl_variant_change", "changeType": "hideControl", - "component": "application.i.Component", + "component": "application.j.Component", "content": {}, "selector": { "id": "control1" }, "layer": "VENDOR", "texts": {}, - "namespace": "apps/application.i.Component/changes", + "namespace": "apps/application.j.Component/changes", "creation": "2025-10-30T13:52:40.4754350Z", "originalLanguage": "", "conditions": {}, diff --git a/test/expected/build/application.i/dest/changes/id_456_addField.change b/test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant_management_change similarity index 52% rename from test/expected/build/application.i/dest/changes/id_456_addField.change rename to test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant_management_change index 0ca9acd3b..1e1f585c8 100644 --- a/test/expected/build/application.i/dest/changes/id_456_addField.change +++ b/test/fixtures/application.j/webapp/changes/id_111_test.ctrl_variant_management_change @@ -1,16 +1,16 @@ { - "fileName": "id_456_addField", - "fileType": "change", + "fileName": "id_111_test", + "fileType": "ctrl_variant_management_change", "changeType": "hideControl", - "component": "application.i.Component", + "component": "application.j.Component", "content": {}, "selector": { "id": "control1" }, "layer": "VENDOR", "texts": {}, - "namespace": "apps/application.i.Component/changes", - "creation": "2023-10-30T13:52:40.4754350Z", + "namespace": "apps/application.j.Component/changes", + "creation": "2025-10-30T13:52:40.4754350Z", "originalLanguage": "", "conditions": {}, "support": { diff --git a/test/fixtures/application.j/webapp/changes/id_111_variantDependentControlChange.change b/test/fixtures/application.j/webapp/changes/id_111_variantDependentControlChange.change new file mode 100644 index 000000000..bd733b67e --- /dev/null +++ b/test/fixtures/application.j/webapp/changes/id_111_variantDependentControlChange.change @@ -0,0 +1,21 @@ +{ + "fileName": "id_111_variantDependentControlChange", + "fileType": "change", + "changeType": "hideControl", + "component": "application.j.Component", + "content": {}, + "selector": { + "id": "control1" + }, + "layer": "VENDOR", + "texts": {}, + "namespace": "apps/application.j.Component/changes", + "creation": "2025-10-30T13:52:40.4754350Z", + "originalLanguage": "", + "conditions": {}, + "support": { + "generator": "did it", + "user": "Max Mustermann" + }, + "variantReference": "someting here" +} diff --git a/test/fixtures/application.j/webapp/manifest.json b/test/fixtures/application.j/webapp/manifest.json index 476ebb972..97ce1c9a7 100644 --- a/test/fixtures/application.j/webapp/manifest.json +++ b/test/fixtures/application.j/webapp/manifest.json @@ -1,25 +1,26 @@ { - "_version": "1.1.0", - "sap.app": { - "_version": "1.1.0", - "id": "application.j", - "type": "application", - "applicationVersion": { - "version": "1.2.2" - }, - "embeds": ["embedded"], - "title": "{{title}}" - }, + "_version": "1.1.0", + "sap.app": { + "_version": "1.1.0", + "id": "application.j", + "type": "application", + "applicationVersion": { + "version": "1.2.2" + }, + "embeds": ["embedded"], + "title": "{{title}}" + }, "sap.ui5": { "dependencies": { + "minUI5Version": "1.73.2", "libs": { "sap.ui.layout": {}, "sap.ui.core": {}, - "sap.m": {}, - "sap.ui.fl": { - "lazy": true - } + "sap.m": {}, + "sap.ui.fl": { + "lazy": true + } } - } - } + } + } } diff --git a/test/fixtures/lbt/modules/amd_dynamic_require.js b/test/fixtures/lbt/modules/amd_dynamic_require.js new file mode 100644 index 000000000..ac90f9261 --- /dev/null +++ b/test/fixtures/lbt/modules/amd_dynamic_require.js @@ -0,0 +1,11 @@ +sap.ui.define([], function() { + return { + load: function(modName) { + sap.ui.require([modName], function(modExport) { + // module was loaded + }, function(err) { + // error occurred + }); + } + } +}); \ No newline at end of file diff --git a/test/fixtures/lbt/modules/amd_dynamic_require_sync.js b/test/fixtures/lbt/modules/amd_dynamic_require_sync.js new file mode 100644 index 000000000..fdd4a3729 --- /dev/null +++ b/test/fixtures/lbt/modules/amd_dynamic_require_sync.js @@ -0,0 +1,7 @@ +sap.ui.define([], function() { + return { + load: function(modName) { + return sap.ui.requireSync(modName); + } + } +}); diff --git a/test/fixtures/lbt/modules/declare_dynamic_require.js b/test/fixtures/lbt/modules/declare_dynamic_require.js new file mode 100644 index 000000000..d29d573ad --- /dev/null +++ b/test/fixtures/lbt/modules/declare_dynamic_require.js @@ -0,0 +1,5 @@ +jQuery.sap.declare("sap.ui.testmodule"); + +sap.ui.testmodule.load = function(modName) { + jQuery.sap.require(modName); +}; diff --git a/test/fixtures/library.d/main/src/library/d/some.js b/test/fixtures/library.d/main/src/library/d/some.js index 81e734360..fa1d786f7 100644 --- a/test/fixtures/library.d/main/src/library/d/some.js +++ b/test/fixtures/library.d/main/src/library/d/some.js @@ -1,4 +1,7 @@ /*! * ${copyright} */ -console.log('HelloWorld'); \ No newline at end of file +(function() { + var someNonUglifiedVariable = "World"; + console.log('Hello ' + someNonUglifiedVariable); +})(); diff --git a/test/fixtures/library.h/main/src/library/h/.library b/test/fixtures/library.h/main/src/library/h/.library index 8d1e46775..38501ff40 100644 --- a/test/fixtures/library.h/main/src/library/h/.library +++ b/test/fixtures/library.h/main/src/library/h/.library @@ -6,6 +6,14 @@ Some fancy copyright ${version} - Library D + Library H + + + + + + + + diff --git a/test/fixtures/library.h/main/src/library/h/designtime/library.designtime.js b/test/fixtures/library.h/main/src/library/h/designtime/library.designtime.js new file mode 100644 index 000000000..e961048c1 --- /dev/null +++ b/test/fixtures/library.h/main/src/library/h/designtime/library.designtime.js @@ -0,0 +1,14 @@ +/*! + * ${copyright} + */ + +/** + * designtime and global export + */ +var myexport = (function() { + + "use strict"; + + String("asd"); + +}()); diff --git a/test/fixtures/library.h/main/src/library/h/i18n/messagebundle.properties b/test/fixtures/library.h/main/src/library/h/i18n/messagebundle.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/test/fixtures/library.h/main/src/library/h/i18n/messagebundle.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/test/fixtures/library.h/main/src/library/h/i18n/messagebundle_en.properties b/test/fixtures/library.h/main/src/library/h/i18n/messagebundle_en.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/test/fixtures/library.h/main/src/library/h/i18n/messagebundle_en.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/test/fixtures/library.h/main/src/library/h/some.js b/test/fixtures/library.h/main/src/library/h/some.js index f14efacd4..c1a44398b 100644 --- a/test/fixtures/library.h/main/src/library/h/some.js +++ b/test/fixtures/library.h/main/src/library/h/some.js @@ -1,4 +1,5 @@ /*! * ${copyright} */ +//@ui5-bundle-raw-include library/h/other.js console.log(' Some '); diff --git a/test/fixtures/sap.ui.core/main/src/sap/ui/core/.library b/test/fixtures/sap.ui.core/main/src/sap/ui/core/.library index 7efee8324..9089c4f9b 100644 --- a/test/fixtures/sap.ui.core/main/src/sap/ui/core/.library +++ b/test/fixtures/sap.ui.core/main/src/sap/ui/core/.library @@ -8,4 +8,13 @@ Core + + + + + + + + diff --git a/test/fixtures/sap.ui.core/main/src/sap/ui/core/one.js b/test/fixtures/sap.ui.core/main/src/sap/ui/core/one.js new file mode 100644 index 000000000..753bd0523 --- /dev/null +++ b/test/fixtures/sap.ui.core/main/src/sap/ui/core/one.js @@ -0,0 +1,3 @@ +function One(){ + return 1; +} diff --git a/test/fixtures/theme.library.e/package.json b/test/fixtures/theme.library.e/package.json new file mode 100644 index 000000000..d48d4d185 --- /dev/null +++ b/test/fixtures/theme.library.e/package.json @@ -0,0 +1,10 @@ +{ + "name": "theme.library.e", + "version": "1.0.0", + "description": "Simple SAPUI5 based library - test for dev dependencies", + "devDependencies": { + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + } +} diff --git a/test/fixtures/theme.library.e/src/theme/library/e/my_theme/.theme b/test/fixtures/theme.library.e/src/theme/library/e/my_theme/.theme new file mode 100644 index 000000000..4c62f2611 --- /dev/null +++ b/test/fixtures/theme.library.e/src/theme/library/e/my_theme/.theme @@ -0,0 +1,9 @@ + + + + my_theme + me + ${copyright} + ${version} + + \ No newline at end of file diff --git a/test/fixtures/theme.library.e/src/theme/library/e/my_theme/.theming b/test/fixtures/theme.library.e/src/theme/library/e/my_theme/.theming new file mode 100644 index 000000000..83b6c785a --- /dev/null +++ b/test/fixtures/theme.library.e/src/theme/library/e/my_theme/.theming @@ -0,0 +1,27 @@ +{ + "sEntity": "Theme", + "sId": "sap_belize", + "oExtends": "base", + "sVendor": "SAP", + "aBundled": ["sap_belize_plus"], + "mCssScopes": { + "library": { + "sBaseFile": "library", + "sEmbeddingMethod": "APPEND", + "aScopes": [ + { + "sLabel": "Contrast", + "sSelector": "sapContrast", + "sEmbeddedFile": "sap_belize_plus.library", + "sEmbeddedCompareFile": "library", + "sThemeIdSuffix": "Contrast", + "sThemability": "PUBLIC", + "aThemabilityFilter": [ + "Color" + ], + "rExcludeSelector": "\\.sapContrastPlus\\W" + } + ] + } + } +} diff --git a/test/fixtures/theme.library.e/src/theme/library/e/my_theme/library.source.less b/test/fixtures/theme.library.e/src/theme/library/e/my_theme/library.source.less new file mode 100644 index 000000000..ba66d46d7 --- /dev/null +++ b/test/fixtures/theme.library.e/src/theme/library/e/my_theme/library.source.less @@ -0,0 +1,18 @@ +/*! + * ${copyright} + */ + +* { + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-touch-callout: none; + -webkit-text-size-adjust: none; + -ms-text-size-adjust: none; +} + +.sapUiBody { + width: 100%; + height: 100%; + margin: 0; + font-family: @sapUiFontFamily; + font-size: 1rem; +} diff --git a/test/fixtures/theme.library.e/test/theme/library/e/Test.html b/test/fixtures/theme.library.e/test/theme/library/e/Test.html new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/theme.library.e/ui5.yaml b/test/fixtures/theme.library.e/ui5.yaml new file mode 100644 index 000000000..cf89c2432 --- /dev/null +++ b/test/fixtures/theme.library.e/ui5.yaml @@ -0,0 +1,9 @@ +--- +specVersion: "1.1" +type: theme-library +metadata: + name: theme.library.e + copyright: |- + UI development toolkit for HTML5 (OpenUI5) + * (c) Copyright 2009-xxx SAP SE or an SAP affiliate company. + * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. diff --git a/test/lib/builder/BuildContext.js b/test/lib/builder/BuildContext.js new file mode 100644 index 000000000..1021fce32 --- /dev/null +++ b/test/lib/builder/BuildContext.js @@ -0,0 +1,72 @@ +const test = require("ava"); +const sinon = require("sinon"); +const mock = require("mock-require"); + +test.afterEach.always((t) => { + sinon.restore(); + mock.stopAll(); +}); + +const BuildContext = require("../../../lib/builder/BuildContext"); + +test("Missing parameters", (t) => { + const error = t.throws(() => { + new BuildContext({}); + }); + + t.is(error.message, `Missing parameter 'rootProject'`, "Threw with expected error message"); +}); + +test("getRootProject", (t) => { + const buildContext = new BuildContext({ + rootProject: "pony" + }); + + t.is(buildContext.getRootProject(), "pony", "Returned correct value"); +}); + +test.serial("createProjectContext", (t) => { + class DummyProjectContext { + constructor({buildContext, project, resources}) { + t.is(buildContext, testBuildContext, "Correct buildContext parameter"); + t.is(project, "project", "Correct project parameter"); + t.is(resources, "resources", "Correct resources parameter"); + } + } + mock("../../../lib/builder/ProjectBuildContext", DummyProjectContext); + + const BuildContext = mock.reRequire("../../../lib/builder/BuildContext"); + const testBuildContext = new BuildContext({ + rootProject: "pony" + }); + + const projectContext = testBuildContext.createProjectContext({ + project: "project", + resources: "resources" + }); + + t.true(projectContext instanceof DummyProjectContext, + "Project context is an instance of DummyProjectContext"); + t.is(testBuildContext.projectBuildContexts[0], projectContext, + "BuildContext stored correct ProjectBuildContext"); +}); + +test("executeCleanupTasks", async (t) => { + const buildContext = new BuildContext({ + rootProject: "pony" + }); + + const executeCleanupTasks = sinon.stub().resolves(); + + buildContext.projectBuildContexts.push({ + executeCleanupTasks + }); + buildContext.projectBuildContexts.push({ + executeCleanupTasks + }); + + await buildContext.executeCleanupTasks(); + + t.is(executeCleanupTasks.callCount, 2, + "Project context executeCleanupTasks got called twice"); +}); diff --git a/test/lib/builder/ProjectBuildContext.js b/test/lib/builder/ProjectBuildContext.js new file mode 100644 index 000000000..d14b3072c --- /dev/null +++ b/test/lib/builder/ProjectBuildContext.js @@ -0,0 +1,120 @@ +const test = require("ava"); +const sinon = require("sinon"); +const mock = require("mock-require"); + +test.afterEach.always((t) => { + sinon.restore(); + mock.stopAll(); +}); + +const ProjectBuildContext = require("../../../lib/builder/ProjectBuildContext"); + +test("Missing parameters", (t) => { + const error = t.throws(() => { + new ProjectBuildContext({}); + }); + + t.is(error.message, `One or more mandatory parameters are missing`, "Threw with expected error message"); +}); + +test("isRootProject: true", (t) => { + const projectBuildContext = new ProjectBuildContext({ + buildContext: { + getRootProject: () => "root project" + }, + project: "root project", + resources: "resources" + }); + + t.true(projectBuildContext.isRootProject(), "Correctly identified root project"); +}); + +test("isRootProject: false", (t) => { + const projectBuildContext = new ProjectBuildContext({ + buildContext: { + getRootProject: () => "root project" + }, + project: "no root project", + resources: "resources" + }); + + t.false(projectBuildContext.isRootProject(), "Correctly identified non-root project"); +}); + +test("registerCleanupTask", (t) => { + const projectBuildContext = new ProjectBuildContext({ + buildContext: { + getRootProject: () => "root project" + }, + project: "no root project", + resources: "resources" + }); + projectBuildContext.registerCleanupTask("my task 1"); + projectBuildContext.registerCleanupTask("my task 2"); + + t.is(projectBuildContext.queues.cleanup[0], "my task 1", "Cleanup task registered"); + t.is(projectBuildContext.queues.cleanup[1], "my task 2", "Cleanup task registered"); +}); + +test("executeCleanupTasks", (t) => { + const projectBuildContext = new ProjectBuildContext({ + buildContext: { + getRootProject: () => "root project" + }, + project: "no root project", + resources: "resources" + }); + const task1 = sinon.stub().resolves(); + const task2 = sinon.stub().resolves(); + projectBuildContext.registerCleanupTask(task1); + projectBuildContext.registerCleanupTask(task2); + + projectBuildContext.executeCleanupTasks(); + + t.is(task1.callCount, 1, "Cleanup task 1 got called"); + t.is(task2.callCount, 1, "my task 2", "Cleanup task 2 got called"); +}); + +test("STANDARD_TAGS constant", (t) => { + const projectBuildContext = new ProjectBuildContext({ + buildContext: { + getRootProject: () => "root project" + }, + project: "no root project", + resources: "resources" + }); + + t.deepEqual(projectBuildContext.STANDARD_TAGS, { + OmitFromBuildResult: "ui5:OmitFromBuildResult", + IsBundle: "ui5:IsBundle" + }, "Exposes correct STANDARD_TAGS constant"); +}); + +test.serial("getResourceTagCollection", (t) => { + class DummyResourceTagCollection { + constructor({allowedTags}) { + t.deepEqual(allowedTags, [ + "ui5:OmitFromBuildResult", + "ui5:IsBundle" + ], + "Correct allowedTags parameter supplied"); + } + } + mock("@ui5/fs", { + ResourceTagCollection: DummyResourceTagCollection + }); + + const ProjectBuildContext = mock.reRequire("../../../lib/builder/ProjectBuildContext"); + const projectBuildContext = new ProjectBuildContext({ + buildContext: { + getRootProject: () => "root project" + }, + project: "no root project", + resources: "resources" + }); + + const collection = projectBuildContext.getResourceTagCollection(); + + t.true(collection instanceof DummyResourceTagCollection, + "Returned an instance of mocked DummyResourceTagCollection"); +}); diff --git a/test/lib/builder/builder.js b/test/lib/builder/builder.js index 63bb671d1..cc16b5a29 100644 --- a/test/lib/builder/builder.js +++ b/test/lib/builder/builder.js @@ -8,6 +8,7 @@ const readFile = promisify(fs.readFile); const assert = chai.assert; const sinon = require("sinon"); const mock = require("mock-require"); +const resourceFactory = require("@ui5/fs").resourceFactory; const ui5Builder = require("../../../"); const builder = ui5Builder.builder; @@ -16,6 +17,7 @@ const applicationGPath = path.join(__dirname, "..", "..", "fixtures", "applicati const applicationHPath = path.join(__dirname, "..", "..", "fixtures", "application.h"); const applicationIPath = path.join(__dirname, "..", "..", "fixtures", "application.i"); const applicationJPath = path.join(__dirname, "..", "..", "fixtures", "application.j"); +const collectionPath = path.join(__dirname, "..", "..", "fixtures", "collection"); const libraryDPath = path.join(__dirname, "..", "..", "fixtures", "library.d"); const libraryEPath = path.join(__dirname, "..", "..", "fixtures", "library.e"); const libraryHPath = path.join(__dirname, "..", "..", "fixtures", "library.h"); @@ -54,7 +56,7 @@ function cloneProjectTree(tree) { return clone; } -async function checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath) { +async function checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath) { for (let i = 0; i < expectedFiles.length; i++) { const expectedFile = expectedFiles[i]; const relativeFile = path.relative(expectedPath, expectedFile); @@ -65,9 +67,18 @@ async function checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, des if (expectedFile.endsWith("sap-ui-cachebuster-info.json")) { currentContent = JSON.parse(currentContent.replace(/(:\s+)(\d+)/g, ": 0")); expectedContent = JSON.parse(expectedContent.replace(/(:\s+)(\d+)/g, ": 0")); - assert.deepEqual(currentContent, expectedContent); + t.deepEqual(currentContent, expectedContent); } else { - assert.equal(currentContent.replace(newLineRegexp, "\n"), expectedContent.replace(newLineRegexp, "\n")); + if (expectedFile.endsWith(".json")) { + try { + t.deepEqual(JSON.parse(currentContent), JSON.parse(expectedContent), expectedFile); + } catch (e) { + t.falsy(e, expectedFile); + } + } + t.is(currentContent.replace(newLineRegexp, "\n"), + expectedContent.replace(newLineRegexp, "\n"), + relativeFile); } }; await Promise.all([currentFileContentPromise, expectedFileContentPromise]).then(assertContents); @@ -76,9 +87,93 @@ async function checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, des test.afterEach.always((t) => { sinon.restore(); + mock.stopAll(); +}); + +test.serial("Build", async (t) => { + class DummyBuildContext { + constructor({rootProject}) { + t.deepEqual(rootProject, applicationATree, "Correct rootProject parameter"); + } + } + const getTagStub = sinon.stub().returns(); + const getResourceTagCollectionStub = sinon.stub().returns({ + getTag: getTagStub + }); + const isRootProjectStub = sinon.stub().returns(true); + const dummyProjectContext = { + getResourceTagCollection: getResourceTagCollectionStub, + isRootProject: isRootProjectStub, + STANDARD_TAGS: { + OmitFromBuildResult: "đź‘»" + } + }; + const createProjectContextStub = sinon.stub().returns(dummyProjectContext); + const executeCleanupTasksStub = sinon.stub().resolves(); + DummyBuildContext.prototype.createProjectContext = createProjectContextStub; + DummyBuildContext.prototype.executeCleanupTasks = executeCleanupTasksStub; + mock("../../../lib/builder/BuildContext", DummyBuildContext); + + class DummyTaskUtil { + constructor({projectBuildContext}) { + t.is(projectBuildContext, dummyProjectContext, "Correct projectBuildContext parameter"); + } + } + mock("../../../lib/tasks/TaskUtil", DummyTaskUtil); + + const applicationType = require("../../../lib/types/application/applicationType"); + const appBuildStub = sinon.stub(applicationType, "build").resolves(); + + const builder = mock.reRequire("../../../lib/builder/builder"); + + const destPath = "./test/tmp/build/build"; + await builder.build({ + tree: applicationATree, + destPath + }); + + t.is(createProjectContextStub.callCount, 1, "One project context got created"); + const createProjectContextParams = createProjectContextStub.getCall(0).args[0]; + t.is(createProjectContextParams.project, applicationATree, "Correct project provided to projectContext"); + t.truthy(createProjectContextParams.resources.workspace, "resources.workspace object provided to projectContext"); + t.truthy(createProjectContextParams.resources.dependencies, + "resources.dependencies object provided to projectContext"); + t.deepEqual(Object.keys(createProjectContextParams), ["project", "resources"], + "resource and project parameters provided"); + + t.is(appBuildStub.callCount, 1, "Build called once"); + const appBuildParams = appBuildStub.getCall(0).args[0]; + t.is(Object.keys(appBuildParams).length, 5, "Five parameters provided to types build function"); + t.is(appBuildParams.project, applicationATree, "Correct project provided to type"); + t.truthy(appBuildParams.resourceCollections, "resourceCollections object provided to type"); + t.truthy(appBuildParams.resourceCollections.workspace, "resources.workspace object provided to type"); + t.truthy(appBuildParams.resourceCollections.dependencies, "resources.dependencies object provided to type"); + t.deepEqual(appBuildParams.tasks, [ + "replaceCopyright", + "replaceVersion", + "createDebugFiles", + "escapeNonAsciiCharacters", + "uglify", + "buildThemes", + "generateLibraryManifest", + "generateVersionInfo", + "generateFlexChangesBundle", + "generateComponentPreload", + "generateBundle", + "generateLibraryPreload" + ], "Correct tasks provided to type"); + t.truthy(appBuildParams.parentLogger, "parentLogger object provided to type"); + t.true(appBuildParams.taskUtil instanceof DummyTaskUtil, "Correct taskUtil instance provided to type"); + + t.is(getResourceTagCollectionStub.callCount, 1, "getResourceTagCollection called once"); + t.is(getTagStub.callCount, 2, "getTag called once"); + t.deepEqual(getTagStub.getCall(0).args[1], "đź‘»", "First getTag call with expected tag name"); + t.deepEqual(getTagStub.getCall(1).args[1], "đź‘»", "Second getTag call with expected tag name"); + t.is(isRootProjectStub.callCount, 2, "isRootProject called once"); + t.is(executeCleanupTasksStub.callCount, 1, "Cleanup called once"); }); -test("Build application.a", (t) => { +test.serial("Build application.a", (t) => { const destPath = "./test/tmp/build/application.a/dest"; const expectedPath = path.join("test", "expected", "build", "application.a", "dest"); @@ -92,14 +187,13 @@ test("Build application.a", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); - -test("Build application.a with error", async (t) => { +test.serial("Build application.a with error", async (t) => { const destPath = "./test/tmp/build/application.a/dest"; const error = await t.throwsAsync(builder.build({ @@ -109,7 +203,125 @@ test("Build application.a with error", async (t) => { t.deepEqual(error.message, `Unknown type 'non existent'`); }); -test("Build application.a [dev mode]", (t) => { +test.serial("Build application.a with dependencies", (t) => { + const destPath = "./test/tmp/build/application.a/dest-deps"; + const expectedPath = path.join("test", "expected", "build", "application.a", "dest-deps"); + + return builder.build({ + tree: applicationATree, + destPath, + excludedTasks: [ + "generateComponentPreload", "generateStandaloneAppBundle", "generateVersionInfo", + "generateLibraryPreload", "escapeNonAsciiCharacters", "generateLibraryManifest" + ], + buildDependencies: true + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build application.a with dependencies include", (t) => { + const destPath = "./test/tmp/build/application.a/dest-deps-incl"; + const expectedPath = path.join("test", "expected", "build", "application.a", "dest-deps"); + + return builder.build({ + tree: applicationATree, + destPath, + excludedTasks: [ + "generateComponentPreload", "generateStandaloneAppBundle", "generateVersionInfo", + "generateLibraryPreload", "escapeNonAsciiCharacters", "generateLibraryManifest" + ], + buildDependencies: true, includedDependencies: ["*"] + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build application.a with dependencies exclude", (t) => { + const destPath = "./test/tmp/build/application.a/dest-deps-excl"; + const expectedPath = path.join("test", "expected", "build", "application.a", "dest-deps-excl"); + + return builder.build({ + tree: applicationATree, + destPath, + excludedTasks: [ + "generateComponentPreload", "generateStandaloneAppBundle", "generateVersionInfo", + "generateLibraryPreload", "escapeNonAsciiCharacters", "generateLibraryManifest" + ], + buildDependencies: true, excludedDependencies: ["library.d"] + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build application.a self-contained", (t) => { + const destPath = "./test/tmp/build/application.a/dest-self"; + const expectedPath = path.join("test", "expected", "build", "application.a", "dest-self"); + + return builder.build({ + tree: applicationATree, + destPath, + excludedTasks: ["generateComponentPreload", "generateVersionInfo"], + selfContained: true + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build application.a with dependencies self-contained", (t) => { + const destPath = "./test/tmp/build/application.a/dest-depself"; + const expectedPath = path.join("test", "expected", "build", "application.a", "dest-depself"); + + return builder.build({ + tree: applicationATree, + destPath, + excludedTasks: [ + "generateComponentPreload", "generateVersionInfo", "escapeNonAsciiCharacters", + "generateLibraryManifest" + ], + buildDependencies: true, + selfContained: true + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build application.a [dev mode]", (t) => { const destPath = "./test/tmp/build/application.a/dest-dev"; const expectedPath = path.join("test", "expected", "build", "application.a", "dest-dev"); @@ -124,13 +336,13 @@ test("Build application.a [dev mode]", (t) => { assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.a and clean target path [dev mode]", (t) => { +test.serial("Build application.a and clean target path [dev mode]", (t) => { const destPath = "./test/tmp/build/application.a/dest-clean"; const destPathRubbishSubFolder = destPath + "/rubbish-should-be-deleted"; const expectedPath = path.join("test", "expected", "build", "application.a", "dest-dev"); @@ -152,13 +364,13 @@ test("Build application.a and clean target path [dev mode]", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.g", (t) => { +test.serial("Build application.g", (t) => { const destPath = "./test/tmp/build/application.g/dest"; const expectedPath = path.join("test", "expected", "build", "application.g", "dest"); @@ -172,13 +384,13 @@ test("Build application.g", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.g with component preload paths", (t) => { +test.serial("Build application.g with component preload paths", (t) => { const destPath = "./test/tmp/build/application.g/dest2"; const expectedPath = path.join("test", "expected", "build", "application.g", "dest"); @@ -192,13 +404,13 @@ test("Build application.g with component preload paths", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.g with excludes", (t) => { +test.serial("Build application.g with excludes", (t) => { const destPath = "./test/tmp/build/application.g/excludes"; const expectedPath = path.join("test", "expected", "build", "application.g", "excludes"); @@ -213,13 +425,13 @@ test("Build application.g with excludes", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.h", (t) => { +test.serial("Build application.h", (t) => { const destPath = "./test/tmp/build/application.h/dest"; const expectedPath = path.join("test", "expected", "build", "application.h", "dest"); @@ -234,13 +446,13 @@ test("Build application.h", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.i", (t) => { +test.serial("Build application.i", (t) => { const destPath = "./test/tmp/build/application.i/dest"; const expectedPath = path.join("test", "expected", "build", "application.i", "dest"); @@ -254,13 +466,13 @@ test("Build application.i", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build application.j", (t) => { +test.serial("Build application.j", (t) => { const destPath = "./test/tmp/build/application.j/dest"; const expectedPath = path.join("test", "expected", "build", "application.j", "dest"); @@ -274,13 +486,58 @@ test("Build application.j", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build application.j with resources.json and version info", (t) => { + const destPath = "./test/tmp/build/application.j/dest-resources-json"; + const expectedPath = path.join("test", "expected", "build", "application.j", "dest-resources-json"); + + + const dummyVersionInfoGenerator = () => { + const versionJson = { + "name": "application.j", + "version": "1.0.0", + "buildTimestamp": "202008120917", + "scmRevision": "", + "libraries": [] + }; + + return [resourceFactory.createResource({ + path: "/resources/sap-ui-version.json", + string: JSON.stringify(versionJson, null, "\t") + })]; + }; + + mock("../../../lib/processors/versionInfoGenerator", dummyVersionInfoGenerator); + mock.reRequire("../../../lib/tasks/generateVersionInfo"); + + const builder = mock.reRequire("../../../lib/builder/builder"); + + + return builder.build({ + includedTasks: [ + "generateResourcesJson" + ], + tree: applicationJTree, + destPath, + excludedTasks: ["createDebugFiles", "generateStandaloneAppBundle"] + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build library.d with copyright from .library file", (t) => { +test.serial("Build library.d with copyright from .library file", (t) => { const destPath = "./test/tmp/build/library.d/dest"; const expectedPath = path.join("test", "expected", "build", "library.d", "dest"); @@ -295,13 +552,13 @@ test("Build library.d with copyright from .library file", (t) => { assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build library.e with copyright from settings of ui5.yaml", (t) => { +test.serial("Build library.e with copyright from settings of ui5.yaml", (t) => { const destPath = path.join("test", "tmp", "build", "library.e", "dest"); const expectedPath = path.join("test", "expected", "build", "library.e", "dest"); @@ -316,13 +573,13 @@ test("Build library.e with copyright from settings of ui5.yaml", (t) => { assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build library.h with custom bundles and component-preloads", (t) => { +test.serial("Build library.h with custom bundles and component-preloads", (t) => { const destPath = path.join("test", "tmp", "build", "library.h", "dest"); const expectedPath = path.join("test", "expected", "build", "library.h", "dest"); @@ -337,13 +594,37 @@ test("Build library.h with custom bundles and component-preloads", (t) => { assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build library.h with custom bundles and component-preloads with resources.json", (t) => { + const destPath = path.join("test", "tmp", "build", "library.h", "dest-resources-json"); + const expectedPath = path.join("test", "expected", "build", "library.h", "dest-resources-json"); + + return builder.build({ + includedTasks: [ + "generateResourcesJson" + ], + tree: libraryHTree, + destPath, + excludedTasks: ["createDebugFiles", "generateLibraryPreload"] + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build library.i with manifest info taken from .library and library.js", (t) => { +test.serial("Build library.i with manifest info taken from .library and library.js", (t) => { const destPath = path.join("test", "tmp", "build", "library.i", "dest"); const expectedPath = path.join("test", "expected", "build", "library.i", "dest"); @@ -358,13 +639,13 @@ test("Build library.i with manifest info taken from .library and library.js", (t assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build library.j with JSDoc build only", (t) => { +test.serial("Build library.j with JSDoc build only", (t) => { const destPath = path.join("test", "tmp", "build", "library.j", "dest"); const expectedPath = path.join("test", "expected", "build", "library.j", "dest"); @@ -380,13 +661,13 @@ test("Build library.j with JSDoc build only", (t) => { assert.directoryDeepEqual(destPath, expectedPath); // Check for all file contents - return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); }).then(() => { t.pass(); }); }); -test("Build theme.j even without an library", (t) => { +test.serial("Build theme.j even without an library", (t) => { const destPath = "./test/tmp/build/theme.j/dest"; const expectedPath = "./test/expected/build/theme.j/dest"; return builder.build({ @@ -398,21 +679,37 @@ test("Build theme.j even without an library", (t) => { // Check for all directories and files assert.directoryDeepEqual(destPath, expectedPath); - // Check for all file contents - expectedFiles.forEach((expectedFile) => { - const relativeFile = path.relative(expectedPath, expectedFile); - const destFile = path.join(destPath, relativeFile); - assert.fileEqual(destFile, expectedFile); - t.pass(); - }); + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + +test.serial("Build theme.j even without an library with resources.json", (t) => { + const destPath = "./test/tmp/build/theme.j/dest-resources-json"; + const expectedPath = "./test/expected/build/theme.j/dest-resources-json"; + return builder.build({ + includedTasks: [ + "generateResourcesJson" + ], + tree: themeJTree, + destPath + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + + return checkFileContentsIgnoreLineFeeds(t, expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); }); }); test.serial("Cleanup", async (t) => { const BuildContext = require("../../../lib/builder/BuildContext"); - const projectContext = "project context"; - const createProjectContextStub = sinon.stub(BuildContext.prototype, "createProjectContext").returns(projectContext); - const executeCleanupTasksStub = sinon.stub(BuildContext.prototype, "executeCleanupTasks").returns(projectContext); + const createProjectContextStub = sinon.spy(BuildContext.prototype, "createProjectContext"); + const executeCleanupTasksStub = sinon.stub(BuildContext.prototype, "executeCleanupTasks").resolves(); const applicationType = require("../../../lib/types/application/applicationType"); const appBuildStub = sinon.stub(applicationType, "build").resolves(); @@ -441,10 +738,11 @@ test.serial("Cleanup", async (t) => { t.deepEqual(appBuildStub.callCount, 1, "Build called once"); t.deepEqual(createProjectContextStub.callCount, 1, "One project context got created"); const createProjectContextParams = createProjectContextStub.getCall(0).args[0]; + t.truthy(createProjectContextParams.project, "project object provided"); t.truthy(createProjectContextParams.resources.workspace, "resources.workspace object provided"); t.truthy(createProjectContextParams.resources.dependencies, "resources.dependencies object provided"); - t.deepEqual(Object.keys(createProjectContextParams), ["resources"], - "resource parameter (and no others) provided"); + t.deepEqual(Object.keys(createProjectContextParams), ["project", "resources"], + "resource and project parameters provided"); t.deepEqual(executeCleanupTasksStub.callCount, 1, "Cleanup called once"); // Error case @@ -462,41 +760,71 @@ test.serial("Cleanup", async (t) => { t.deepEqual(executeCleanupTasksStub.callCount, 2, "Cleanup called twice"); }); -const applicationATree = { - "id": "application.a", + +const libraryDTree = { + "id": "library.d", "version": "1.0.0", - "path": applicationAPath, + "path": libraryDPath, "dependencies": [ { - "id": "library.d", + "id": "sap.ui.core-evo", "version": "1.0.0", - "path": path.join(applicationAPath, "node_modules", "library.d"), + "path": libraryCore, "dependencies": [], "_level": 1, "specVersion": "0.1", "type": "library", "metadata": { - "name": "library.d", - "namespace": "library/d", + "name": "sap.ui.core", + "namespace": "sap/ui/core", "copyright": "Some fancy copyright" }, "resources": { "configuration": { "paths": { - "src": "main/src", - "test": "main/test" + "src": "main/src" } }, "pathMappings": { - "/resources/": "main/src", - "/test-resources/": "main/test" + "/resources/": "main/src" } } + } + ], + "_level": 0, + "_isRoot": true, + "specVersion": "0.1", + "type": "library", + "metadata": { + "name": "library.d", + "namespace": "library/d", + "copyright": "Some fancy copyright" + }, + "resources": { + "configuration": { + "paths": { + "src": "main/src", + "test": "main/test" + }, + "propertiesFileSourceEncoding": "ISO-8859-1" }, + "pathMappings": { + "/resources/": "main/src", + "/test-resources/": "main/test" + } + } +}; + +const applicationATree = { + "id": "application.a", + "version": "1.0.0", + "path": applicationAPath, + "dependencies": [ + libraryDTree, { "id": "library.a", "version": "1.0.0", - "path": path.join(applicationAPath, "node_modules", "collection", "library.a"), + "path": path.join(collectionPath, "library.a"), "dependencies": [], "_level": 1, "specVersion": "0.1", @@ -522,7 +850,7 @@ const applicationATree = { { "id": "library.b", "version": "1.0.0", - "path": path.join(applicationAPath, "node_modules", "collection", "library.b"), + "path": path.join(collectionPath, "library.b"), "dependencies": [], "_level": 1, "specVersion": "0.1", @@ -548,7 +876,7 @@ const applicationATree = { { "id": "library.c", "version": "1.0.0", - "path": path.join(applicationAPath, "node_modules", "collection", "library.c"), + "path": path.join(collectionPath, "library.c"), "dependencies": [], "_level": 1, "specVersion": "0.1", @@ -573,10 +901,12 @@ const applicationATree = { } ], "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { - "name": "application.a" + "name": "application.a", + "namespace": "application/a" }, "resources": { "configuration": { @@ -591,12 +921,12 @@ const applicationATree = { } }; - const applicationATreeBadType = { "id": "application.a", "version": "1.0.0", "path": applicationAPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "non existent", "metadata": { @@ -620,6 +950,7 @@ const applicationGTree = { "version": "1.0.0", "path": applicationGPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { @@ -655,6 +986,7 @@ const applicationGTreeWithExcludes = { "version": "1.0.0", "path": applicationGPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { @@ -691,6 +1023,7 @@ const applicationGTreeComponentPreloadPaths = { "version": "1.0.0", "path": applicationGPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { @@ -724,6 +1057,7 @@ const applicationHTree = { "version": "1.0.0", "path": applicationHPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { @@ -785,6 +1119,7 @@ const applicationITree = { "version": "1.0.0", "path": applicationIPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { @@ -813,6 +1148,7 @@ const applicationJTree = { "version": "1.0.0", "path": applicationJPath, "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "application", "metadata": { @@ -836,59 +1172,6 @@ const applicationJTree = { } }; -const libraryDTree = { - "id": "library.d", - "version": "1.0.0", - "path": libraryDPath, - "dependencies": [ - { - "id": "sap.ui.core-evo", - "version": "1.0.0", - "path": libraryCore, - "dependencies": [], - "_level": 1, - "specVersion": "0.1", - "type": "library", - "metadata": { - "name": "sap.ui.core", - "namespace": "sap/ui/core", - "copyright": "Some fancy copyright" - }, - "resources": { - "configuration": { - "paths": { - "src": "main/src" - } - }, - "pathMappings": { - "/resources/": "main/src" - } - } - } - ], - "_level": 0, - "specVersion": "0.1", - "type": "library", - "metadata": { - "name": "library.d", - "namespace": "library/d", - "copyright": "Some fancy copyright" - }, - "resources": { - "configuration": { - "paths": { - "src": "main/src", - "test": "main/test" - }, - "propertiesFileSourceEncoding": "ISO-8859-1" - }, - "pathMappings": { - "/resources/": "main/src", - "/test-resources/": "main/test" - } - } -}; - const libraryETree = { "id": "library.e", "version": "1.0.0", @@ -920,12 +1203,14 @@ const libraryETree = { } ], "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "library", "metadata": { "name": "library.e", "namespace": "library/e", - "copyright": "UI development toolkit for HTML5 (OpenUI5)\n * (c) Copyright 2009-xxx SAP SE or an SAP affiliate company.\n * Licensed under the Apache License, Version 2.0 - see LICENSE.txt." + "copyright": "UI development toolkit for HTML5 (OpenUI5)\n * (c) Copyright 2009-xxx SAP SE or an " + + "SAP affiliate company.\n * Licensed under the Apache License, Version 2.0 - see LICENSE.txt." }, "resources": { "configuration": { @@ -973,6 +1258,7 @@ const libraryHTree = { } ], "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "library", "metadata": { @@ -1004,11 +1290,19 @@ const libraryHTree = { "library/h/some.js", "library/h/library.js", "library/h/file.js", - "!library/h/not.js", "!library/h/components/" ], "resolve": false, "renderer": false + }, { + "mode": "raw", + "filters": [ + "library/h/not.js" + ], + "resolve": true, + "declareModules": false, + "sort": true, + "renderer": false }] }, "bundleOptions": { @@ -1059,6 +1353,7 @@ const libraryITree = { cloneProjectTree(libraryDTree) ], "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "library", "metadata": { @@ -1086,6 +1381,7 @@ const libraryJTree = { "path": libraryJPath, "dependencies": [], "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "library", "metadata": { @@ -1111,6 +1407,7 @@ const themeJTree = { "path": themeJPath, "dependencies": [], "_level": 0, + "_isRoot": true, "specVersion": "0.1", "type": "library", "metadata": { diff --git a/test/lib/index.js b/test/lib/index.js new file mode 100644 index 000000000..5ec816d78 --- /dev/null +++ b/test/lib/index.js @@ -0,0 +1,49 @@ +const test = require("ava"); +const index = require("../../index"); + +test("index.js exports all expected modules", (t) => { + t.truthy(index.builder, "Module exported"); + + t.truthy(index.processors.flexChangesBundler, "Module exported"); + t.truthy(index.processors.manifestBundler, "Module exported"); + t.truthy(index.processors.moduleBundler, "Module exported"); + t.truthy(index.processors.apiIndexGenerator, "Module exported"); + t.truthy(index.processors.jsdocGenerator, "Module exported"); + t.truthy(index.processors.sdkTransformer, "Module exported"); + t.truthy(index.processors.bootstrapHtmlTransformer, "Module exported"); + t.truthy(index.processors.debugFileCreator, "Module exported"); + t.truthy(index.processors.resourceCopier, "Module exported"); + t.truthy(index.processors.nonAsciiEscaper, "Module exported"); + t.truthy(index.processors.stringReplacer, "Module exported"); + t.truthy(index.processors.themeBuilder, "Module exported"); + t.truthy(index.processors.uglifier, "Module exported"); + t.truthy(index.processors.versionInfoGenerator, "Module exported"); + + t.truthy(index.tasks.generateComponentPreload, "Module exported"); + t.truthy(index.tasks.generateFlexChangesBundle, "Module exported"); + t.truthy(index.tasks.generateLibraryPreload, "Module exported"); + t.truthy(index.tasks.generateManifestBundle, "Module exported"); + t.truthy(index.tasks.generateStandaloneAppBundle, "Module exported"); + t.truthy(index.tasks.generateBundle, "Module exported"); + t.truthy(index.tasks.generateCachebusterInfo, "Module exported"); + t.truthy(index.tasks.buildThemes, "Module exported"); + t.truthy(index.tasks.createDebugFiles, "Module exported"); + t.truthy(index.tasks.executeJsdocSdkTransformation, "Module exported"); + t.truthy(index.tasks.generateApiIndex, "Module exported"); + t.truthy(index.tasks.generateJsdoc, "Module exported"); + t.truthy(index.tasks.generateVersionInfo, "Module exported"); + t.truthy(index.tasks.escapeNonAsciiCharacters, "Module exported"); + t.truthy(index.tasks.replaceCopyright, "Module exported"); + t.truthy(index.tasks.replaceVersion, "Module exported"); + t.truthy(index.tasks.transformBootstrapHtml, "Module exported"); + t.truthy(index.tasks.uglify, "Module exported"); + t.truthy(index.tasks.taskRepository, "Module exported"); + + t.truthy(index.types.AbstractBuilder, "Module exported"); + t.truthy(index.types.AbstractFormatter, "Module exported"); + t.truthy(index.types.application, "Module exported"); + t.truthy(index.types.library, "Module exported"); + t.truthy(index.types.themeLibrary, "Module exported"); + t.truthy(index.types.module, "Module exported"); + t.truthy(index.types.typeRepository, "Module exported"); +}); diff --git a/test/lib/lbt/analyzer/ComponentAnalyzer.js b/test/lib/lbt/analyzer/ComponentAnalyzer.js index 15ea083ee..db9852dcc 100644 --- a/test/lib/lbt/analyzer/ComponentAnalyzer.js +++ b/test/lib/lbt/analyzer/ComponentAnalyzer.js @@ -480,6 +480,68 @@ test("_analyzeManifest: Manifest with routing and routes object", async (t) => { "addDependency should be called with the app dependency name"); }); +test("_analyzeManifest: Manifest with legacy routes object", async (t) => { + const manifest = { + "sap.ui5": { + routing: { + config: { + viewPath: "test.view", + viewType: "XML" + }, + routes: { + test: { + pattern: "", + view: "App", + targetAggregation: "pages", + targetControl: "app", + } + } + } + } + }; + + const moduleInfo = { + addDependency: function() {} + }; + const stubAddDependency = sinon.spy(moduleInfo, "addDependency"); + + const analyzer = new ComponentAnalyzer(); + + await analyzer._analyzeManifest(manifest, moduleInfo); + + // Note: Dependencies to views within legacy routes are not collected + t.true(stubAddDependency.calledOnce, "addDependency was called once"); + t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/core/routing/Router.js", + "addDependency should be called with the router dependency name"); +}); + +test("_analyzeManifest: Manifest with empty routes array", async (t) => { + const manifest = { + "sap.ui5": { + routing: { + config: { + viewPath: "test.view", + viewType: "XML" + }, + routes: [] + } + } + }; + + const moduleInfo = { + addDependency: function() {} + }; + const stubAddDependency = sinon.spy(moduleInfo, "addDependency"); + + const analyzer = new ComponentAnalyzer(); + + await analyzer._analyzeManifest(manifest, moduleInfo); + + t.true(stubAddDependency.calledOnce, "addDependency was called once"); + t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/core/routing/Router.js", + "addDependency should be called with the router dependency name"); +}); + test("_analyzeManifest: Manifest with rootview object", async (t) => { const manifest = { "sap.ui5": { diff --git a/test/lib/lbt/analyzer/JSModuleAnalyzer.js b/test/lib/lbt/analyzer/JSModuleAnalyzer.js index 6994305f0..5015b5024 100644 --- a/test/lib/lbt/analyzer/JSModuleAnalyzer.js +++ b/test/lib/lbt/analyzer/JSModuleAnalyzer.js @@ -9,10 +9,12 @@ const EXPECTED_MODULE_NAME = "sap/ui/testmodule.js"; const EXPECTED_DECLARE_DEPENDENCIES = [ "jquery.sap.global.js", - "top/require/void.js", "top/require/var.js", "top/require/assign.js", "top/requireSync/var.js", "top/requireSync/assign.js", - "block/require/void.js", "block/require/var.js", "block/require/assign.js", "block/requireSync/var.js", "block/requireSync/assign.js", - "nested/scope/require/void.js", "nested/scope/require/var.js", "nested/scope/require/assign.js", "nested/scope/requireSync/var.js", "nested/scope/requireSync/assign.js", - "nested/scope2/require/void.js", "nested/scope2/require/var.js", "nested/scope2/require/assign.js", "nested/scope2/requireSync/var.js", "nested/scope2/requireSync/assign.js" + "top/require/void.js", "top/require/var.js", "top/require/assign.js", "top/requireSync/var.js", + "top/requireSync/assign.js", "block/require/void.js", "block/require/var.js", "block/require/assign.js", + "block/requireSync/var.js", "block/requireSync/assign.js", "nested/scope/require/void.js", + "nested/scope/require/var.js", "nested/scope/require/assign.js", "nested/scope/requireSync/var.js", + "nested/scope/requireSync/assign.js", "nested/scope2/require/void.js", "nested/scope2/require/var.js", + "nested/scope2/require/assign.js", "nested/scope2/requireSync/var.js", "nested/scope2/requireSync/assign.js" ]; const EXPECTED_DEFINE_DEPENDENCIES_NO_LEGACY = [ @@ -39,9 +41,7 @@ function analyze(file, name) { reject(err); } try { - const ast = esprima.parseScript(buffer.toString(), {comment: true}); - const info = new ModuleInfo(name); - new JSModuleAnalyzer().analyze(ast, name, info); + const info = analyzeString(buffer.toString(), name); resolve(info); } catch (execErr) { reject(execErr); @@ -50,6 +50,13 @@ function analyze(file, name) { }); } +function analyzeString(content, name) { + const ast = esprima.parseScript(content, {comment: true}); + const info = new ModuleInfo(name); + new JSModuleAnalyzer().analyze(ast, name, info); + return info; +} + function assertModuleNamesEqual(t, actual, expected, msg) { actual.sort(); expected.sort(); @@ -67,7 +74,8 @@ function analyzeModule( expectedDependencies, expectedConditionalDependencies, expectedSubmodules, - ignoreImplicitDependencies + ignoreImplicitDependencies, + rawModule ) { // analyze(file, name).then( (info) => { @@ -94,24 +102,41 @@ function analyzeModule( expectedSubmodules, "submodules should match"); } - }).then(() => t.end(), () => t.end()); + t.false(info.dynamicDependencies, + "no use of dynamic dependencies should have been detected"); + if (rawModule) { + t.true(info.rawModule, + "raw module"); + } else { + t.false(info.rawModule, + "ui5 module"); + } + }).then(() => t.end(), (e) => t.fail(`failed to analyze module with error: ${e.message}`)); } -test.cb("DeclareToplevel", analyzeModule, "modules/declare_toplevel.js", EXPECTED_MODULE_NAME, EXPECTED_DECLARE_DEPENDENCIES); +test.cb("DeclareToplevel", analyzeModule, + "modules/declare_toplevel.js", EXPECTED_MODULE_NAME, EXPECTED_DECLARE_DEPENDENCIES); -test.cb("DeclareFunctionExprScope", analyzeModule, "modules/declare_function_expr_scope.js", EXPECTED_MODULE_NAME, EXPECTED_DECLARE_DEPENDENCIES); +test.cb("DeclareFunctionExprScope", analyzeModule, + "modules/declare_function_expr_scope.js", EXPECTED_MODULE_NAME, EXPECTED_DECLARE_DEPENDENCIES); -test.cb("DeclareFunctionInvocationScope", analyzeModule, "modules/declare_function_invocation_scope.js", EXPECTED_MODULE_NAME, EXPECTED_DECLARE_DEPENDENCIES); +test.cb("DeclareFunctionInvocationScope", analyzeModule, + "modules/declare_function_invocation_scope.js", EXPECTED_MODULE_NAME, EXPECTED_DECLARE_DEPENDENCIES); -test.cb("DefineToplevelNamed", analyzeModule, "modules/define_toplevel_named.js", EXPECTED_MODULE_NAME, EXPECTED_DEFINE_DEPENDENCIES_NO_LEGACY); +test.cb("DefineToplevelNamed", analyzeModule, + "modules/define_toplevel_named.js", EXPECTED_MODULE_NAME, EXPECTED_DEFINE_DEPENDENCIES_NO_LEGACY); -test.cb("DefineToplevelUnnamed", analyzeModule, "modules/define_toplevel_unnamed.js", "modules/define_toplevel_unnamed.js", EXPECTED_DEFINE_DEPENDENCIES_NO_LEGACY); +test.cb("DefineToplevelUnnamed", analyzeModule, + "modules/define_toplevel_unnamed.js", "modules/define_toplevel_unnamed.js", EXPECTED_DEFINE_DEPENDENCIES_NO_LEGACY); -test.cb("DefineWithLegacyCalls", analyzeModule, "modules/define_with_legacy_calls.js", "modules/define_with_legacy_calls.js", EXPECTED_DEFINE_DEPENDENCIES_WITH_LEGACY); +test.cb("DefineWithLegacyCalls", analyzeModule, + "modules/define_with_legacy_calls.js", "modules/define_with_legacy_calls.js", + EXPECTED_DEFINE_DEPENDENCIES_WITH_LEGACY); test.cb("OldStyleModuleWithoutDeclare", function(t) { analyze("modules/no_declare_but_requires.js", null).then((info) => { t.is(info.name, null, "module name should be null"); + t.true(info.rawModule, "raw module"); assertModuleNamesEqual(t, info.dependencies, ["dependency1.js", "dependency2.js", "jquery.sap.global.js"], @@ -120,7 +145,9 @@ test.cb("OldStyleModuleWithoutDeclare", function(t) { }); }); -test.cb("NotAnUI5Module", analyzeModule, "modules/not_a_module.js", "modules/not_a_module.js", NO_DEPENDENCIES); +test.cb("NotAnUI5Module", analyzeModule, + "modules/not_a_module.js", "modules/not_a_module.js", + NO_DEPENDENCIES, NO_DEPENDENCIES, NO_DEPENDENCIES, NO_DEPENDENCIES, true); test.cb("AMDSpecialDependenciesShouldBeIgnored", (t) => { analyzeModule(t, @@ -237,7 +264,42 @@ test.cb("OldStyleBundle", (t) => { analyzeModule(t, "modules/bundle-oldstyle.js", "sap-ui-core.js", - [], + [ + "jquery.sap.dom.js", + "jquery.sap.script.js", + "sap/ui/base/Object.js", + "sap/ui/base/BindingParser.js", + "sap/ui/base/EventProvider.js", + "sap/ui/base/ManagedObjectMetadata.js", + "sap/ui/model/BindingMode.js", + "sap/ui/model/CompositeBinding.js", + "sap/ui/model/Context.js", + "sap/ui/model/FormatException.js", + "sap/ui/model/ListBinding.js", + "sap/ui/model/Model.js", + "sap/ui/model/ParseException.js", + "sap/ui/model/TreeBinding.js", + "sap/ui/model/Type.js", + "sap/ui/model/ValidateException.js", + "jquery.sap.strings.js", + "sap/ui/Global.js", + "sap/ui/base/Interface.js", + "sap/ui/core/Component.js", + "sap/ui/core/Configuration.js", + "sap/ui/core/Control.js", + "sap/ui/core/Element.js", + "sap/ui/core/ElementMetadata.js", + "sap/ui/core/FocusHandler.js", + "sap/ui/core/RenderManager.js", + "sap/ui/core/ResizeHandler.js", + "sap/ui/core/ThemeCheck.js", + "sap/ui/core/UIArea.js", + "sap/ui/core/message/MessageManager.js", + "jquery.sap.mobile.js", + "jquery.sap.properties.js", + "jquery.sap.resources.js", + "jquery.sap.sjax.js" + ], [], [ "sap/ui/Device.js", @@ -264,7 +326,42 @@ test.cb("OldStyleBundleV2", (t) => { analyzeModule(t, "modules/bundle-oldstyle-v2.js", "sap-ui-core.js", - [], + [ + "jquery.sap.dom.js", + "jquery.sap.script.js", + "sap/ui/base/Object.js", + "sap/ui/base/BindingParser.js", + "sap/ui/base/EventProvider.js", + "sap/ui/base/ManagedObjectMetadata.js", + "sap/ui/model/BindingMode.js", + "sap/ui/model/CompositeBinding.js", + "sap/ui/model/Context.js", + "sap/ui/model/FormatException.js", + "sap/ui/model/ListBinding.js", + "sap/ui/model/Model.js", + "sap/ui/model/ParseException.js", + "sap/ui/model/TreeBinding.js", + "sap/ui/model/Type.js", + "sap/ui/model/ValidateException.js", + "jquery.sap.strings.js", + "sap/ui/Global.js", + "sap/ui/base/Interface.js", + "sap/ui/core/Component.js", + "sap/ui/core/Configuration.js", + "sap/ui/core/Control.js", + "sap/ui/core/Element.js", + "sap/ui/core/ElementMetadata.js", + "sap/ui/core/FocusHandler.js", + "sap/ui/core/RenderManager.js", + "sap/ui/core/ResizeHandler.js", + "sap/ui/core/ThemeCheck.js", + "sap/ui/core/UIArea.js", + "sap/ui/core/message/MessageManager.js", + "jquery.sap.mobile.js", + "jquery.sap.properties.js", + "jquery.sap.resources.js", + "jquery.sap.sjax.js" + ], [], [ "sap/ui/Device.js", @@ -287,13 +384,64 @@ test.cb("OldStyleBundleV2", (t) => { ); }); -// Note: this test still fails as the evo-style bundles don't declare the names of the -// contained raw-modules any longer. test.cb("EvoBundle", (t) => { analyzeModule(t, "modules/bundle-evo.js", "sap-ui-core.js", - [], + [ + "sap/base/util/now.js", + "sap/base/util/Version.js", + "sap/ui/dom/getComputedStyleFix.js", + "sap/ui/dom/activeElementFix.js", + "sap/ui/dom/includeScript.js", + "sap/ui/dom/includeStylesheet.js", + "sap/ui/core/support/Hotkeys.js", + "sap/ui/security/FrameOptions.js", + "sap/ui/performance/Measurement.js", + "sap/ui/performance/trace/Interaction.js", + "sap/ui/base/syncXHRFix.js", + "sap/base/util/LoaderExtensions.js", + "sap/base/util/defineLazyProperty.js", + "sap/base/util/ObjectPath.js", + "sap/base/util/isPlainObject.js", + "sap/ui/base/Object.js", + "sap/ui/base/BindingParser.js", + "sap/ui/base/EventProvider.js", + "sap/ui/base/ManagedObjectMetadata.js", + "sap/ui/model/BindingMode.js", + "sap/ui/model/StaticBinding.js", + "sap/ui/model/CompositeBinding.js", + "sap/ui/model/Context.js", + "sap/ui/model/FormatException.js", + "sap/ui/model/ParseException.js", + "sap/ui/model/Type.js", + "sap/ui/model/ValidateException.js", + "sap/ui/base/SyncPromise.js", + "sap/ui/util/ActivityDetection.js", + "sap/base/util/deepClone.js", + "sap/base/util/deepEqual.js", + "sap/base/util/uid.js", + "sap/ui/Global.js", + "sap/ui/base/Interface.js", + "sap/ui/core/Component.js", + "sap/ui/core/Configuration.js", + "sap/ui/core/Control.js", + "sap/ui/core/Element.js", + "sap/ui/core/ElementMetadata.js", + "sap/ui/core/FocusHandler.js", + "sap/ui/core/RenderManager.js", + "sap/ui/core/ResizeHandler.js", + "sap/ui/core/ThemeCheck.js", + "sap/ui/core/UIArea.js", + "sap/ui/core/message/MessageManager.js", + "sap/ui/dom/getScrollbarSize.js", + "sap/base/i18n/ResourceBundle.js", + "sap/base/util/array/uniqueSort.js", + "sap/ui/performance/trace/initTraces.js", + "sap/base/util/isEmptyObject.js", + "sap/base/util/each.js", + "sap/ui/events/jquery/EventSimulation.js" + ], [], [ "sap/ui/thirdparty/baseuri.js", @@ -332,7 +480,10 @@ test("Bundle", (t) => { "todo/view/App.view.xml" ]; t.deepEqual(info.subModules, expected, "module dependencies should match"); - t.truthy(info.dependencies.every((dep) => !info.isConditionalDependency(dep)), "none of the dependencies must be 'conditional'"); + t.truthy(info.dependencies.every((dep) => !info.isConditionalDependency(dep)), + "none of the dependencies must be 'conditional'"); + t.false(info.rawModule, + "ui5 module"); }); }); @@ -358,7 +509,177 @@ test("ES6 Syntax", (t) => { "only dependencies to 'conditional/*' modules should be conditional"); t.is(info.isImplicitDependency(dep), !/^(?:conditional|static)\//.test(dep), "all dependencies other than 'conditional/*' and 'static/*' should be implicit"); + t.false(info.dynamicDependencies, + "no use of dynamic dependencies should have been detected"); + t.false(info.rawModule, + "ui5 module"); }); }); }); +test("Dynamic import (declare/require)", (t) => { + return analyze("modules/declare_dynamic_require.js").then((info) => { + t.true(info.dynamicDependencies, + "the use of dynamic dependencies should have been detected"); + t.false(info.rawModule, + "ui5 module"); + }); +}); + +test("Dynamic import (define/require)", (t) => { + return analyze("modules/amd_dynamic_require.js").then((info) => { + t.true(info.dynamicDependencies, + "the use of dynamic dependencies should have been detected"); + t.false(info.rawModule, + "ui5 module"); + }); +}); + +test("Dynamic import (define/requireSync)", (t) => { + return analyze("modules/amd_dynamic_require_sync.js").then((info) => { + t.true(info.dynamicDependencies, + "the use of dynamic dependencies should have been detected"); + t.false(info.rawModule, + "ui5 module"); + }); +}); + +test("Nested require", (t) => { + const content = ` +(function(deps, callback) { + function doIt(array, callback) { + callback(); + } + + var aArray = []; + doIt(aArray, function() { + doIt(["foo"], function() { + doIt(["bar"], function() { + // nested sap.ui.require + sap.ui.require(deps, callback); + }); + }); + }); +}([ + "my/dependency" +], function(myDep) { + console.log("done") +}));`; + const info = analyzeString(content, "modules/nestedRequire.js"); + t.true(info.rawModule, "raw module"); +}); + +test("Toplevel define", (t) => { + const content = ` +(function() { + function defineMyFile() { + sap.ui.define('def/MyFile', ['dep/myDep'], + function(myDep) { + return 47; + }); + } + + // conditional + if (!(window.sap && window.sap.ui && window.sap.ui.define)) { + var fnHandler = function() { + defineMyFile(); + }; + my.addEventListener("myevent", fnHandler); + } else { + defineMyFile(); + } +}()); `; + const info = analyzeString(content, "modules/functionDefine.js"); + t.true(info.rawModule, "raw module"); +}); + +test("Invalid ui5 bundle comment", (t) => { + const content = `/@ui5-bundles sap/ui/thirdparty/xxx.js +if(!('xxx'in Node.prototype)){} +//@ui5-bundle-raw-includes sap/ui/thirdparty/aaa.js +(function(g,f){g.AAA=f();}(this,(function(){}))); +sap.ui.define("my/module", ["sap/ui/core/UIComponent"],function(n){"use strict";return 47+n});`; + const info = analyzeString(content, "modules/bundle-evo_invalid_comment.js"); + t.is(info.name, "my/module.js", + "module name matches"); + t.deepEqual(info.subModules, [], + "no submodules"); +}); + +test("Declare two times", (t) => { + const content = `jQuery.sap.declare("sap.ui.testmodule"); +sap.ui.testmodule.load = function(modName) { + jQuery.sap.require(modName); +}; +jQuery.sap.declare("sap.ui.testmodule");`; + const info = analyzeString(content, "modules/declare_times_two.js"); + t.is(info.name, "sap/ui/testmodule.js", + "module name matches"); + t.deepEqual(info.subModules, [], + "no submodules"); +}); + +test("Declare dynamic name", (t) => { + const content = `var sCommonName = "sap.ui" +jQuery.sap.declare(sCommonName + ".testmodule"); + +sap.ui.testmodule.load = function(modName) { + jQuery.sap.require(modName); +};`; + const info = analyzeString(content, "modules/dynamic_name.js"); + t.is(info.name, "modules/dynamic_name.js", + "module name matches"); + t.deepEqual(info.subModules, [], + "no submodules"); +}); + +test("jQuery.sap.registerPreloadedModules (with Identifier)", (t) => { + const content = ` +var data = {}; +jQuery.sap.registerPreloadedModules(data); +`; + const info = analyzeString(content, "modules/registerPreloadedModules-Identifier.js"); + t.deepEqual(info.subModules, [], + "no submodules"); +}); + +test("jQuery.sap.registerPreloadedModules (with ObjectExpression)", (t) => { + const content = ` +jQuery.sap.registerPreloadedModules({ + "modules": { + "foo.bar": "" + } +}); +`; + const info = analyzeString(content, "modules/registerPreloadedModules-ObjectExpression.js"); + t.deepEqual(info.subModules, ["foo/bar.js"], + "submodule from jQuery.sap.registerPreloadedModules"); +}); + +test("jQuery.sap.registerPreloadedModules (with ObjectExpression, version 1.0)", (t) => { + const content = ` +jQuery.sap.registerPreloadedModules({ + "modules": { + "foo.bar": "" + }, + "version": "1.0" +}); +`; + const info = analyzeString(content, "modules/registerPreloadedModules-ObjectExpression.js"); + t.deepEqual(info.subModules, ["foo/bar.js"], + "submodule from jQuery.sap.registerPreloadedModules"); +}); + +test("jQuery.sap.registerPreloadedModules (with ObjectExpression, version 2.0)", (t) => { + const content = ` +jQuery.sap.registerPreloadedModules({ + "modules": { + "foo/bar.js": "" + }, + "version": "2.0" +}); +`; + const info = analyzeString(content, "modules/registerPreloadedModules-ObjectExpression.js"); + t.deepEqual(info.subModules, ["foo/bar.js"], + "submodule from jQuery.sap.registerPreloadedModules"); +}); diff --git a/test/lib/lbt/analyzer/SmartTemplateAnalyzer.js b/test/lib/lbt/analyzer/SmartTemplateAnalyzer.js index 392c50533..1c8195c0c 100644 --- a/test/lib/lbt/analyzer/SmartTemplateAnalyzer.js +++ b/test/lib/lbt/analyzer/SmartTemplateAnalyzer.js @@ -201,6 +201,9 @@ test.serial("_analyzeTemplateComponent: Manifest with TemplateAssembler code", a return { buffer: async () => "" }; + }, + getIgnoreMissingModules() { + return false; } }; @@ -235,6 +238,9 @@ test.serial("_analyzeTemplateComponent: no default template name", async (t) => return { buffer: async () => "" }; + }, + getIgnoreMissingModules() { + return false; } }; @@ -264,6 +270,9 @@ test.serial("_analyzeTemplateComponent: with template name from pageConfig", asy return { buffer: async () => "" }; + }, + getIgnoreMissingModules() { + return false; } }; @@ -289,6 +298,78 @@ test.serial("_analyzeTemplateComponent: with template name from pageConfig", asy stubParse.restore(); }); +test.serial("_analyzeTemplateComponent: dependency not found", async (t) => { + const moduleInfo = { + addDependency: function() {} + }; + const stubAddDependency = sinon.spy(moduleInfo, "addDependency"); + + const mockPool = { + async findResource() { + throw new Error(`resource not found in pool: 'pony'`); + }, + getIgnoreMissingModules() { + return false; + } + }; + + const analyzer = new SmartTemplateAnalyzer(mockPool); + + const stubAnalyzeAST = sinon.stub(analyzer, "_analyzeAST").returns(""); + const stubParse = sinon.stub(esprima, "parse").returns(""); + + const error = await t.throwsAsync(analyzer._analyzeTemplateComponent("pony", { + component: { + settings: { + templateName: "donkey" + } + } + }, moduleInfo)); + + t.deepEqual(error.message, `resource not found in pool: 'pony'`); + + t.is(stubAnalyzeAST.callCount, 0, "_analyzeManifest was not called"); + + t.is(stubAddDependency.callCount, 0, "addDependency was not called"); + stubAnalyzeAST.restore(); + stubParse.restore(); +}); + +test.serial("_analyzeTemplateComponent: dependency not found is ignored", async (t) => { + const moduleInfo = { + addDependency: function() {} + }; + const stubAddDependency = sinon.spy(moduleInfo, "addDependency"); + + const mockPool = { + async findResource() { + throw new Error(`resource not found in pool: 'pony'`); + }, + getIgnoreMissingModules() { + return true; // Missing dependency error can be ignored + } + }; + + const analyzer = new SmartTemplateAnalyzer(mockPool); + + const stubAnalyzeAST = sinon.stub(analyzer, "_analyzeAST").returns(""); + const stubParse = sinon.stub(esprima, "parse").returns(""); + + await analyzer._analyzeTemplateComponent("pony", { + component: { + settings: { + templateName: "donkey" + } + } + }, moduleInfo); + + t.is(stubAnalyzeAST.callCount, 0, "_analyzeManifest was not called"); + + t.is(stubAddDependency.callCount, 0, "addDependency was not called"); + stubAnalyzeAST.restore(); + stubParse.restore(); +}); + test("_analyzeAST: get template name from ast", async (t) => { const code = `sap.ui.define(["a", "sap/suite/ui/generic/template/lib/TemplateAssembler"], function(a, TemplateAssembler){ diff --git a/test/lib/lbt/analyzer/XMLTemplateAnalyzer.js b/test/lib/lbt/analyzer/XMLTemplateAnalyzer.js index b5b1c3471..9922c9435 100644 --- a/test/lib/lbt/analyzer/XMLTemplateAnalyzer.js +++ b/test/lib/lbt/analyzer/XMLTemplateAnalyzer.js @@ -3,6 +3,18 @@ const XMLTemplateAnalyzer = require("../../../../lib/lbt/analyzer/XMLTemplateAna const ModuleInfo = require("../../../../lib/lbt/resources/ModuleInfo"); const sinon = require("sinon"); +const mock = require("mock-require"); + +test.afterEach.always((t) => { + mock.stopAll(); + sinon.restore(); +}); + + +const fakeMockPool = { + findResource: () => Promise.resolve() +}; + test("integration: Analysis of an xml view", async (t) => { const xml = ` @@ -13,15 +25,10 @@ test("integration: Analysis of an xml view", async (t) => { `; - const mockPool = {async findResource(name) { - return { - buffer: () => name.endsWith(".xml") ? JSON.stringify(xml): "test" - }; - }}; const moduleInfo = new ModuleInfo(); - const analyzer = new XMLTemplateAnalyzer(mockPool); + const analyzer = new XMLTemplateAnalyzer(fakeMockPool); await analyzer.analyzeView(xml, moduleInfo); t.deepEqual(moduleInfo.dependencies, [ @@ -39,15 +46,10 @@ test("integration: Analysis of an xml view with data binding in properties", asy controllerName="myController"> `; - const mockPool = {async findResource(name) { - return { - buffer: () => name.endsWith(".xml") ? JSON.stringify(xml): "test" - }; - }}; const moduleInfo = new ModuleInfo(); - const analyzer = new XMLTemplateAnalyzer(mockPool); + const analyzer = new XMLTemplateAnalyzer(fakeMockPool); await analyzer.analyzeView(xml, moduleInfo); t.deepEqual(moduleInfo.dependencies, [ @@ -59,6 +61,157 @@ test("integration: Analysis of an xml view with data binding in properties", asy "Implicit dependency should be added since an XMLView is analyzed"); }); +test.serial("integration: Analysis of an xml view with core:require from databinding", async (t) => { + const logger = require("@ui5/logger"); + const errorLogStub = sinon.stub(); + const myLoggerInstance = { + error: errorLogStub + }; + sinon.stub(logger, "getLogger").returns(myLoggerInstance); + const XMLTemplateAnalyzerWithStubbedLogger = mock.reRequire("../../../../lib/lbt/analyzer/XMLTemplateAnalyzer"); + + const xml = ` + + + + + + + +