diff --git a/packages/cli/.chglog/CHANGELOG.tpl.md b/packages/cli/.chglog/CHANGELOG.tpl.md
new file mode 100755
index 00000000000..8cbea05002f
--- /dev/null
+++ b/packages/cli/.chglog/CHANGELOG.tpl.md
@@ -0,0 +1,1389 @@
+# Changelog
+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).
+
+{{ if .Versions -}}
+A list of unreleased changes can be found [here]({{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD).
+{{ end -}}
+
+{{ range .Versions }}
+
+## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
+{{ range .CommitGroups -}}
+### {{ .Title }}
+{{ range .Commits -}}
+- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} [`{{ .Hash.Short }}`]({{ $.Info.RepositoryURL }}/commit/{{ .Hash.Long }})
+{{ end }}
+{{ end -}}
+
+{{- if .RevertCommits -}}
+### Reverts
+{{ range .RevertCommits -}}
+- {{ .Revert.Header }}
+{{ end }}
+{{ end -}}
+
+{{- if .NoteGroups -}}
+{{ range .NoteGroups -}}
+### {{ .Title }}
+{{ range .Notes }}
+{{ .Body }}
+{{ end }}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+
+## [v3.11.1] - 2024-07-22
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.5.0 to 3.5.1 [`00c050f`](https://github.com/SAP/ui5-cli/commit/00c050f929aa6204a5d57ead9845dd24fe5f8704)
+
+
+## [v3.11.0] - 2024-06-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.9.1 to 3.9.2 [`e74c280`](https://github.com/SAP/ui5-cli/commit/e74c28018eafb9b15da56dcb45de58fbedec5ced)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.4.1 to 3.5.0 [`d8bf229`](https://github.com/SAP/ui5-cli/commit/d8bf2295933998e64c4241942b2d93cb663eb068)
+
+
+## [v3.10.3] - 2024-05-22
+
+
+## [v3.10.2] - 2024-05-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 3.2.0 to 3.2.1 [`f8bc6b3`](https://github.com/SAP/ui5-cli/commit/f8bc6b343c0d8cdbfcc37cbca36699b0cc9e9e36)
+
+
+
+## [v3.10.1] - 2024-05-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.4.0 to 3.4.1 [`7c072df`](https://github.com/SAP/ui5-cli/commit/7c072df00fa205d083c68934dac42a9abec94dcc)
+
+
+
+## [v3.10.0] - 2024-04-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.5 to 3.2.0 [`3aae04d`](https://github.com/SAP/ui5-cli/commit/3aae04d9e60c162d42d6e5c75906cdb563bbe761)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.3.1 to 3.4.0 [`023693e`](https://github.com/SAP/ui5-cli/commit/023693e4790a6c7f2ba12492fd5868f27234620e)
+
+
+
+## [v3.9.2] - 2024-03-27
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.3.0 to 3.3.1 [`c1d3b76`](https://github.com/SAP/ui5-cli/commit/c1d3b76dc0670f0a65334d269b804c1a49a82dba)
+
+
+
+## [v3.9.1] - 2024-02-13
+
+
+## [v3.9.0] - 2024-01-18
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.2.0 to 3.3.0 [`9b3f5fd`](https://github.com/SAP/ui5-cli/commit/9b3f5fdfb636a45bd78472ade475b5ac9343dd92)
+
+
+
+## [v3.8.0] - 2023-12-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.8.0 to 3.9.0 [`09f1ea9`](https://github.com/SAP/ui5-cli/commit/09f1ea9310d95636a87a6017a5d264594234b798)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.4 to 3.1.5 [`191b80c`](https://github.com/SAP/ui5-cli/commit/191b80c123840a7556385f08a964bf0f514813a7)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.1.1 to 3.2.0 [`d63a77e`](https://github.com/SAP/ui5-cli/commit/d63a77ec25c98f1f2c2ba3dbbfc69aea95c5ea6a)
+
+### Features
+- Add option to redefine output directory structure ([#665](https://github.com/SAP/ui5-cli/issues/665)) [`388dc79`](https://github.com/SAP/ui5-cli/commit/388dc793fe2344f1f59717f3a9d1ea230b0337dd)
+
+
+
+## [v3.7.3] - 2023-12-01
+
+
+## [v3.7.2] - 2023-11-21
+### Bug Fixes
+- **ui5 init:** Improve error message ([#661](https://github.com/SAP/ui5-cli/issues/661)) [`07e68b0`](https://github.com/SAP/ui5-cli/commit/07e68b00ff5cd2e80c0b1b52fa644e27752ccecb)
+- **ui5.yaml:** Use double quotes for string values ([#660](https://github.com/SAP/ui5-cli/issues/660)) [`c30e371`](https://github.com/SAP/ui5-cli/commit/c30e371be147d859539afbe9a44cc03202a8c870)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.3 to 3.8.0 [`2566170`](https://github.com/SAP/ui5-cli/commit/25661708c2b84f9c21d326c2d4ccb84464d7d2b5)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.3 to 3.1.4 [`2c90ff5`](https://github.com/SAP/ui5-cli/commit/2c90ff542dd5862603ebd0cc927ca71cd243cb8c)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.1.0 to 3.1.1 [`7b97356`](https://github.com/SAP/ui5-cli/commit/7b973566aa647ba1e2b271fa1c77b1bd7025c9ca)
+
+
+
+## [v3.7.1] - 2023-10-20
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.2 to 3.7.3 [`c59d1fb`](https://github.com/SAP/ui5-cli/commit/c59d1fb7577a17590c55b111fb1bcbd30c3ba425)
+
+
+
+## [v3.7.0] - 2023-10-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.1 to 3.7.2 [`0cba692`](https://github.com/SAP/ui5-cli/commit/0cba6927b847d205241bb86628468a22ccd0b999)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.9 to 3.1.0 [`0230f09`](https://github.com/SAP/ui5-cli/commit/0230f0965f146af99095a738899fd048d98218c9)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.4 to 3.0.5 [`e0da997`](https://github.com/SAP/ui5-cli/commit/e0da997b5e4e09f7509f2bf095b85bcf65b491ff)
+
+
+
+## [v3.6.1] - 2023-10-02
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.0 to 3.7.1 [`3f2d021`](https://github.com/SAP/ui5-cli/commit/3f2d021f01c1506281f264caed8643cac5af66a7)
+
+
+
+## [v3.6.0] - 2023-09-06
+### Bug Fixes
+- Update help description for "use" and "--framework-version" [`b042542`](https://github.com/SAP/ui5-cli/commit/b0425423ecd56ff8a24feaf3c7526ffeafe6d11f)
+- Ensure usage of provided UI5 data dir [`d7aaf35`](https://github.com/SAP/ui5-cli/commit/d7aaf35b69f2705860d229415db46cf751aea6b2)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.6.0 to 3.7.0 [`ecf52b4`](https://github.com/SAP/ui5-cli/commit/ecf52b4ab5c4d7c2b3c497e59fb220a350906a94)
+
+
+
+## [v3.5.0] - 2023-08-22
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.5.1 to 3.6.0 [`e5627d8`](https://github.com/SAP/ui5-cli/commit/e5627d81c9e66668bb99d128a304d403df9fd224)
+
+
+
+## [v3.4.1] - 2023-10-24
+### Bug Fixes
+- **ui5 config:** Allow usage of all Configuration options ([#645](https://github.com/SAP/ui5-cli/issues/645)) [`78e032e`](https://github.com/SAP/ui5-cli/commit/78e032ebd7d71ee59e6f6fd4f21dc0564e108d44)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.5.0 to 3.5.1 [`4ca30c3`](https://github.com/SAP/ui5-cli/commit/4ca30c3dc4066919f68af47307b4dc8b0bd898f7)
+
+
+
+## [v3.4.0] - 2023-08-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.4.2 to 3.5.0 [`c77a9e1`](https://github.com/SAP/ui5-cli/commit/c77a9e1bc2bd6f2e02c3c629e4c3f348a83e835c)
+
+
+
+## [v3.3.4] - 2023-07-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.8 to 3.0.9 [`efa562e`](https://github.com/SAP/ui5-cli/commit/efa562e0a893466c6b6d362056d17d87b558a94e)
+
+
+
+## [v3.3.3] - 2023-07-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.7 to 3.0.8 [`deba9bc`](https://github.com/SAP/ui5-cli/commit/deba9bcb93354393662035524a28c8d161b9c3f4)
+
+
+
+## [v3.3.2] - 2023-07-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.4.1 to 3.4.2 [`b55c982`](https://github.com/SAP/ui5-cli/commit/b55c98259c43878a36001e47a1e6a3386f706688)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.6 to 3.0.7 [`8d49876`](https://github.com/SAP/ui5-cli/commit/8d49876b4de7e53b93160a1e913a12f8ba935744)
+
+
+
+## [v3.3.1] - 2023-07-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.4.0 to 3.4.1 [`ebf23f4`](https://github.com/SAP/ui5-cli/commit/ebf23f4ed7ed3833579ee462647e626d16e73192)
+
+
+
+## [v3.3.0] - 2023-06-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.3.2 to 3.4.0 [`66d9caa`](https://github.com/SAP/ui5-cli/commit/66d9caa4a3ef50edf246ddf5e308a0b035f9c2a1)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.5 to 3.0.6 [`e504a14`](https://github.com/SAP/ui5-cli/commit/e504a1453feec43d74da9a03f58c47cdfdcfde5f)
+
+
+
+## [v3.2.0] - 2023-06-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.3.1 to 3.3.2 [`a508e96`](https://github.com/SAP/ui5-cli/commit/a508e966fb15de82c64754171fbd2202af3128e3)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.2 to 3.1.3 [`888fc0c`](https://github.com/SAP/ui5-cli/commit/888fc0cf918994cab1e3c84beac757e609a61566)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.4 to 3.0.5 [`1155cfc`](https://github.com/SAP/ui5-cli/commit/1155cfccb57f7d588063999719d1a0814fd7e939)
+
+### Features
+- **SNAPSHOT Consumption:** Add cache-mode parameter ([#633](https://github.com/SAP/ui5-cli/issues/633)) [`61d0865`](https://github.com/SAP/ui5-cli/commit/61d0865416eaee9bfc08195f636c60ad4f64e13f)
+- **ui5 tree:** Add 'level' and 'flat' parameters ([#635](https://github.com/SAP/ui5-cli/issues/635)) [`284d9ea`](https://github.com/SAP/ui5-cli/commit/284d9ea9f75967257859b7763e7b9a09a3b219cf)
+
+
+
+## [v3.1.3] - 2023-05-23
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.3.0 to 3.3.1 [`dbe7657`](https://github.com/SAP/ui5-cli/commit/dbe765789c2998e71dbc2acfe18029400c144159)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.3 to 3.0.4 [`44a7b21`](https://github.com/SAP/ui5-cli/commit/44a7b21618fe2892d6f99d5e97779a43cda24b8d)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.3 to 3.0.4 [`9ed9ce2`](https://github.com/SAP/ui5-cli/commit/9ed9ce206ac22dbe396d10a9ae5f8ff1345c28be)
+
+
+
+## [v3.1.2] - 2023-05-05
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.2.2 to 3.3.0 [`22c1c14`](https://github.com/SAP/ui5-cli/commit/22c1c1407253703e201df57555d94192ef7895d6)
+
+
+
+## [v3.1.1] - 2023-04-27
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.2.1 to 3.2.2 [`defb631`](https://github.com/SAP/ui5-cli/commit/defb6313fc651826876dd9713ee67fba72ced51c)
+
+
+
+## [v3.1.0] - 2023-04-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.2.0 to 3.2.1 [`922fb09`](https://github.com/SAP/ui5-cli/commit/922fb09c9cb6b8f317b8bba55a9a13f152532c73)
+- Bump [@ui5](https://github.com/ui5)/project from 3.1.1 to 3.2.0 [`4619e2f`](https://github.com/SAP/ui5-cli/commit/4619e2fc555987613920a4a30808534cbd70ab79)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.2 to 3.0.3 [`b5fbf4a`](https://github.com/SAP/ui5-cli/commit/b5fbf4adb094ab534d893d0f1e1f45226c52149b)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.2 to 3.0.3 [`c6fd1f8`](https://github.com/SAP/ui5-cli/commit/c6fd1f8c6c4c0d1419cb5820d6d37e173f528d1d)
+
+### Features
+- Add config command ([#618](https://github.com/SAP/ui5-cli/issues/618)) [`9910e30`](https://github.com/SAP/ui5-cli/commit/9910e304b80ca262587e99ab9a6118a4db15c584)
+
+
+
+## [v3.0.7] - 2023-04-12
+### Bug Fixes
+- Exit with code 1 when using unsupported Node.js version [`b232f83`](https://github.com/SAP/ui5-cli/commit/b232f8369a64bac2a1a599fe22d3d1ef03ff6eb0)
+- **init:** Use specVersion 3.0 [`45d0422`](https://github.com/SAP/ui5-cli/commit/45d04228052d2170c3b3c80f096c35d4c1fe0906)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.1.0 to 3.1.1 [`9f995f9`](https://github.com/SAP/ui5-cli/commit/9f995f980c3bef402771bfa3f321422949540e82)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.1 to 3.1.2 [`145a88c`](https://github.com/SAP/ui5-cli/commit/145a88c90e0fda450d7fa6c44b724220736adede)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.1 to 3.0.2 [`caaa457`](https://github.com/SAP/ui5-cli/commit/caaa457f58ba45a79de4fa9ca3c7f594c9eb7f1e)
+- Bump open from 8.4.2 to 9.1.0 [`978c0b4`](https://github.com/SAP/ui5-cli/commit/978c0b432c4c6d1b21ef59b3e10ac0920ce3c934)
+
+
+
+## [v3.0.6] - 2023-03-31
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.4 to 3.1.0 [`676cabf`](https://github.com/SAP/ui5-cli/commit/676cabfec7416bcb023efbedef9821ee860094c6)
+
+
+
+## [v3.0.5] - 2023-03-16
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.0 to 3.1.1 [`c7f9be5`](https://github.com/SAP/ui5-cli/commit/c7f9be51aa42b351c81d3baca1d853d89b906b8c)
+
+
+
+## [v3.0.4] - 2023-03-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.3 to 3.0.4 [`cfbb720`](https://github.com/SAP/ui5-cli/commit/cfbb720bf3b5143a3c42f8ca9a2080bdba0aee89)
+
+
+
+## [v3.0.3] - 2023-03-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.2 to 3.0.3 [`1bef5f8`](https://github.com/SAP/ui5-cli/commit/1bef5f8bac9c2b8e929e1e543a8cbfed14ba079e)
+- Bump [@ui5](https://github.com/ui5)/server from 3.0.1 to 3.1.0 [`11427f4`](https://github.com/SAP/ui5-cli/commit/11427f4ee0cdf2d0c2db6bd7342cf98b246bf06c)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.1 to 3.0.2 [`c978d84`](https://github.com/SAP/ui5-cli/commit/c978d84da354d3284cbe9b2212b55aeefcb469e3)
+
+
+
+## [v3.0.2] - 2023-02-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.1 to 3.0.2 [`56ae640`](https://github.com/SAP/ui5-cli/commit/56ae64000ad23ca17652d5ab2b55366b5495d484)
+
+
+
+## [v3.0.1] - 2023-02-16
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.0 to 3.0.1 [`1dff14d`](https://github.com/SAP/ui5-cli/commit/1dff14d9a3994c5469a5d9e12bec237361c7d35b)
+- Bump [@ui5](https://github.com/ui5)/server from 3.0.0 to 3.0.1 [`d87daa9`](https://github.com/SAP/ui5-cli/commit/d87daa9990fb8039e10fea746925878d636b0d4a)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.0 to 3.0.1 [`c578c4e`](https://github.com/SAP/ui5-cli/commit/c578c4e1072cc547c61d0fce860ecabcee209210)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.0 to 3.0.1 [`80ed971`](https://github.com/SAP/ui5-cli/commit/80ed971e2f0b2ff973a20b1ebc19467bd12b4c35)
+
+
+
+## [v3.0.0] - 2023-02-09
+## Overview
+UI5 Tooling v3 provides general support for ES2022 ECMAScript language features. See [ECMAScript Support](https://sap.github.io/ui5-tooling/v3/pages/ESSupport/) for details.
+
+### Breaking Changes
+- **`@ui5/cli`:**
+ - Adapt to Project Graph APIs ([#413](https://github.com/SAP/ui5-cli/issues/413)) [`945b82b`](https://github.com/SAP/ui5-cli/commit/945b82bc775dc0a711529057908e9f36d8fadb62)
+- **`@ui5/project`:**
+ - Implement Project Graph, build execution [`161f462`](https://github.com/SAP/ui5-project/commit/161f462cf6a9955337fff512007125128c6c39dd)
+- **`@ui5/builder`:**
+ - **generateJsDoc:** Remove internal 'buildContext' parameter [`4ec80c8`](https://github.com/SAP/ui5-builder/commit/4ec80c874e177b658b1cd819431b6cb0660ded87)
+ - Removal of manifestBundler and generateManifestBundle ([#838](https://github.com/SAP/ui5-builder/issues/838)) [`07a5be2`](https://github.com/SAP/ui5-builder/commit/07a5be2b6d9aa23cf78ddd17951c832d6dec7bef)
+ - **JSDoc:** Fail build when jsdoc command failed ([#845](https://github.com/SAP/ui5-builder/issues/845)) [`c2916b4`](https://github.com/SAP/ui5-builder/commit/c2916b4f1d49b5500e4b51143d4e6065ac200eef)
+ - Remove build execution ([#740](https://github.com/SAP/ui5-builder/issues/740)) [`af2e956`](https://github.com/SAP/ui5-builder/commit/af2e956f6cba1275669160328e32df3fffa782d0)
+ - Enable modern preload bundles without dependencies ([#739](https://github.com/SAP/ui5-builder/issues/739)) [`97cfa6c`](https://github.com/SAP/ui5-builder/commit/97cfa6cd3eadff57bcc18816534c7751551ebdb8)
+ - **generateResourcesJson:** Make 'dependencies' parameter mandatory [`268dd16`](https://github.com/SAP/ui5-builder/commit/268dd16091c515ec0c922ea23af437d9aa8bf3ea)
+ - **moduleBundler:** Always default to `optimize: true` ([#685](https://github.com/SAP/ui5-builder/issues/685)) [`de5837c`](https://github.com/SAP/ui5-builder/commit/de5837c43449ea61deae3b2f02f9973f3fa37992)
+- **`@ui5/server`:**
+ - Remove "/proxy" endpoint ([#550](https://github.com/SAP/ui5-server/issues/550)) [`4bdf839`](https://github.com/SAP/ui5-server/commit/4bdf839e96f67ddbc4cb2a18216921d54df4006e)
+ - Require Project Graph ([#479](https://github.com/SAP/ui5-server/issues/479)) [`d62f85a`](https://github.com/SAP/ui5-server/commit/d62f85a193115a587dbf58225e8130318a475023)
+- **`@ui5/fs`:**
+ - Throw an error on write of a resource when path does not starts with virBasePath of the respective adapter ([#453](https://github.com/SAP/ui5-fs/issues/453)) [`d76575f`](https://github.com/SAP/ui5-fs/commit/d76575f8f05a0b6695285200ba595e532620daed)
+ - Clone resources when writing in and reading from the Memory ([#448](https://github.com/SAP/ui5-fs/issues/448)) [`3454bc1`](https://github.com/SAP/ui5-fs/commit/3454bc15be8a6ecd455b49607cb289e69b41d0f0)
+ - **AbstractAdapter:** Virtual base path must end with slash [`6d1f411`](https://github.com/SAP/ui5-fs/commit/6d1f4117a2b8bb1226540fafeec8341e4966177d)
+ - **resourceFactory:** Remove #createCollectionsForTree [`a4d15f6`](https://github.com/SAP/ui5-fs/commit/a4d15f61ae0416051658280bfd2f8635c7ddf44e)
+- **`@ui5/logger`:**
+ - Deprecate advanced APIs in preparation of refactoring [`3aea5e7`](https://github.com/SAP/ui5-logger/commit/3aea5e766f9bda156e8c7e62a2e8c65f613ef7e9)
+
+### Features
+- `@ui5/cli`:
+ - Add build flag "--experimental-css-variables" ([#501](https://github.com/SAP/ui5-cli/issues/501)) [`0b099db`](https://github.com/SAP/ui5-cli/commit/0b099db193ee94aa0bde8373e883fbc54098cd89)
+- `@ui5/project`:
+ - npm/Installer: Do not wrap promise provided by rimraf v4 ([#550](https://github.com/SAP/ui5-project/issues/550)) [`2d1ccda`](https://github.com/SAP/ui5-project/commit/2d1ccda54edd29dabadcb7bad9136bff09da8eac)
+ - specVersion 3.0 ([#522](https://github.com/SAP/ui5-project/issues/522)) [`c5070e5`](https://github.com/SAP/ui5-project/commit/c5070e55d92ced4326cd7611caf3ec9a3da9e7ed)
+ - Introduce SpecificationVersion class ([#431](https://github.com/SAP/ui5-project/issues/431)) [`e57842b`](https://github.com/SAP/ui5-project/commit/e57842b06397a5b36e6373df97f7b7bb91f09741)
+ - **TaskRunner:** Provide taskName and logger instance to custom tasks [`36cd2d8`](https://github.com/SAP/ui5-project/commit/36cd2d83f9a6a92cbd28619d8a25c0ba3f732117)
+ - **TaskUtil:** Add resourceFactory API to v3 interface [`2e863cf`](https://github.com/SAP/ui5-project/commit/2e863cfaf9f8924d0c87fe9dfe01568c1fd979c8)
+ - **TaskUtil:** Add getProject/getDependencies API to interface [`51f2949`](https://github.com/SAP/ui5-project/commit/51f29493f57f094396776bb2686c8a74e8901a7f)
+- `@ui5/builder`:
+ - Support ES2022 language features ([#848](https://github.com/SAP/ui5-builder/issues/848)) [`f9b8457`](https://github.com/SAP/ui5-builder/commit/f9b845726731a0e02ec4a499e2a1a82a639174a8)
+ - **jsdoc:** Support destructuring of enums for defaultValue ([#775](https://github.com/SAP/ui5-builder/issues/775)) [`523f365`](https://github.com/SAP/ui5-builder/commit/523f365cb917997c5031d245309c21e9e4b3e311)
+ - **builder:** Improve support for ES6+ syntax ([#774](https://github.com/SAP/ui5-builder/issues/774)) [`90385fe`](https://github.com/SAP/ui5-builder/commit/90385feb7cea1e5b864cff035b01263a492972a9)
+ - **jsdoc:** Improve support for ES6+ syntax ([#785](https://github.com/SAP/ui5-builder/issues/785)) [`187a6a3`](https://github.com/SAP/ui5-builder/commit/187a6a35000145d70bf41e0d8b724e5ea8d8dc78)
+ - **generateThemeDesignerResources task:** Create css_variables.less ([#730](https://github.com/SAP/ui5-builder/issues/730)) [`34e69be`](https://github.com/SAP/ui5-builder/commit/34e69be95fc8ec1961b24b7e2580c2c993d814d3)
+ - **builder:** Add cssVariables option ([#728](https://github.com/SAP/ui5-builder/issues/728)) [`30d58e1`](https://github.com/SAP/ui5-builder/commit/30d58e1081c1bdc665f13952ecbe5c400b5f4ed7)
+ - Generate source maps for bundles ([#695](https://github.com/SAP/ui5-builder/issues/695)) [`8a20c42`](https://github.com/SAP/ui5-builder/commit/8a20c4257a1ebe4d613b0595be93cd45d900f580)
+ - **replaceVersion/Copyright:** Also process test-resources ([#693](https://github.com/SAP/ui5-builder/issues/693)) [`a0d4bc2`](https://github.com/SAP/ui5-builder/commit/a0d4bc2a80d61e042786207af4bdbda6c3ddfe31)
+ - Support ES2022 language features [`e749b6a`](https://github.com/SAP/ui5-builder/commit/e749b6ae0838f923b27dd0d7d34da2174c433f5f)
+ - Add minify task and processor ([#666](https://github.com/SAP/ui5-builder/issues/666)) [`a3af604`](https://github.com/SAP/ui5-builder/commit/a3af604ff0a12fb9241dcd105cf0aec8d718a299)
+- `@ui5/server`:
+ - **MiddlewareUtil:** Add getProject/getDependencies/resourceFactory API to interface ([#547](https://github.com/SAP/ui5-server/issues/547)) [`ab28f78`](https://github.com/SAP/ui5-server/commit/ab28f789ba929ef1319b6e562267e9717cc9937b)
+- `@ui5/fs`:
+ - Add Link-reader and WriterCollection [`a0e5cf3`](https://github.com/SAP/ui5-fs/commit/a0e5cf3ef86a4b0cdc817d08963ed6574740f1bc)
+ - Introduce Readers "Filter" and "Transformer" ([#331](https://github.com/SAP/ui5-fs/issues/331)) [`f46e6d1`](https://github.com/SAP/ui5-fs/commit/f46e6d1b9aed5858f2d72b10b18635de6ed1f1e0)
+- `@ui5/logger`:
+ - Add new log level "perf" [`acf0c71`](https://github.com/SAP/ui5-logger/commit/acf0c717612f440ea7a114e757c05d358ae523a7)
+
+### Bug Fixes
+- `@ui5/project`:
+ - **ProjectBuilder:** Fix verbose logging for already built projects [`f04ffd2`](https://github.com/SAP/ui5-project/commit/f04ffd2c0ab0270df697c20258474ff536811476)
+ - **ProjectBuilder:** Skip build for projects that do not require to be built [`ac5f1f8`](https://github.com/SAP/ui5-project/commit/ac5f1f891255b56597e51d121329f03786338d4a)
+ - **Specification:** Fix migration for legacy projects that are not applications or libraries [`d89d804`](https://github.com/SAP/ui5-project/commit/d89d8047519ca8f162dc7a225f138ae304871ecb)
+ - Fix build manifest creation [`b1459eb`](https://github.com/SAP/ui5-project/commit/b1459eb26aa8a4b18ad84a369c122c114d64b64b)
+- `@ui5/builder`:
+ - Avoid redundant bundle creation ([#741](https://github.com/SAP/ui5-builder/issues/741)) [`13c8405`](https://github.com/SAP/ui5-builder/commit/13c840585946401d238936dfa38a6f70a73e9ed0)
+ - **JSModuleAnalyzer:** Fix detection of bundle name ([#705](https://github.com/SAP/ui5-builder/issues/705)) [`aaeafd4`](https://github.com/SAP/ui5-builder/commit/aaeafd4a1fd194dd08e5ae47c29d90f0b4c7d197)
+ - **generateResourcesJson:** Add raw-module info for debug bundles ([#736](https://github.com/SAP/ui5-builder/issues/736)) [`3b918e8`](https://github.com/SAP/ui5-builder/commit/3b918e83bfd38342778ecd4c58e648e99ad7cffc)
+ - **LibraryBuilder:** Align task order of "generateComponentPreload" [`aea061d`](https://github.com/SAP/ui5-builder/commit/aea061d9d6c2ac0c11484dcc08bdcda23ab62986)
+ - **LocatorResourcePool:** Wait for resources in prepare step ([#719](https://github.com/SAP/ui5-builder/issues/719)) [`1b7f93f`](https://github.com/SAP/ui5-builder/commit/1b7f93f4988340d7a6575be3191a02e6c295ebd0)
+ - **XMLTemplateAnalyzer:** Analyze core:require of FragmentDefinition [`af075ed`](https://github.com/SAP/ui5-builder/commit/af075edf784d9f1ba162a34f0bf150dbcbc0f479)
+ - **Bundler:** Ensure reproducibility for bundles with multiple parts ([#689](https://github.com/SAP/ui5-builder/issues/689)) [`6f4588b`](https://github.com/SAP/ui5-builder/commit/6f4588b3eb687178e557ac4fb36481104f9681a0)
+ - **generateResourcesJson:** Don't list resources omitted from build result [`9608c51`](https://github.com/SAP/ui5-builder/commit/9608c5177f86494ba689d2e799b4378fec9ed6fa)
+ - **generateResourcesJson:** Analyze debug bundles ([#669](https://github.com/SAP/ui5-builder/issues/669)) [`f27513a`](https://github.com/SAP/ui5-builder/commit/f27513a259b30d39e260790781b6d435b4ab088b)
+ - **Bundler:** Sort raw modules by default [`0e11b69`](https://github.com/SAP/ui5-builder/commit/0e11b6965a1d2e63a96e9b738e38975b5ac755bc)
+- `@ui5/fs`:
+ - **FileSystem Adapter:** Use fs.copy / Skip writing when resource is unchanged ([#370](https://github.com/SAP/ui5-fs/issues/370)) [`9ac6a39`](https://github.com/SAP/ui5-fs/commit/9ac6a39f3cb72e02c2a1298b07c4676a0ee92377)
+ - Allow resource migration ([#407](https://github.com/SAP/ui5-fs/issues/407)) [`1722d71`](https://github.com/SAP/ui5-fs/commit/1722d71b78184cae0dfb092fd3d4c4156924dc28)
+
+## Details
+### Breaking Changes
+Support for older Node.js and npm releases has been dropped for all UI5 Tooling modules.
+Only Node.js v16.18.0 and npm v8 or higher are supported.
+
+All packages have been transformed to ES Modules. Therefore modules are no longer provides a CommonJS exports.
+If your project uses CommonJS, it needs to be converted to ES Modules or use a dynamic import for consuming UI5 Tooling modules.
+
+For more information see also:
+- https://sap.github.io/ui5-tooling/updates/migrate-v3/
+- https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
+
+### @ui5/cli
+- Removed CLI option `--translator`. Use new option `--dependency-definition` to provide a file with
+ static dependency information
+- Removed `ui5 build dev` command
+- Refactored `ui5 tree`: Removed `--full`, `--json` and `--dedupe` options
+
+#### @ui5/project
+- normalizer and projectTree APIs have been removed. Use generateProjectGraph instead
+- Going forward only specification versions 2.0 and higher are supported
+ - In case a legacy specification version is detected, an automatic, transparent migration is attempted.
+- Build:
+ - The "dev" build mode has been removed
+ - The task "generateVersionInfo" is no longer executed for application projects by default. You may enable it again using the includedTasks parameter
+
+#### @ui5/builder
+The `jsdocGenerator` processor and the corresponding `generateJsdoc` task will now throw an error when JSDoc reports an error (exit code != 0). This will also fail the build when running `ui5 build jsdoc`.
+
+The manifestBundler processor and generateManifestBundle task has been removed because it is no longer required for the HTML5 repository in Cloud Foundry.
+
+- builder.js has been removed. Use ui5-project builder instead
+- Tasks now rely on Project instances being available on Resources (see https://github.com/SAP/ui5-fs/pull/381)
+- TaskRepository#addTask has been removed. Custom tasks need to be added to the project graph instead
+- TaskUtil#get/set/clearTag now requires a Project instance to be provided. Path strings are no longer sufficient and will cause an exception to be thrown
+
+For library projects, the task "generateComponentPreload" is now executed after tasks "generateLibraryManifest" and "generateManifestBundle" instead of before them.
+
+The following tasks have been removed:
+
+- createDebugFiles
+- uglify
+
+The following processors have been removed:
+
+- debugFileCreator
+- resourceCopier
+- uglifier
+
+As a replacement, the new 'minify' task and 'minifier' processor can be used.
+
+Note: The minify task is executed earlier, before the bundling process takes place. Existing 'beforeTask' and 'afterTask' configuration of custom tasks might need to be adapted to cater for this change.
+
+#### @ui5/server
+This removes the "/proxy" endpoint and the corresponding "connectUi5Proxy" middleware from the standard ui5-server. Internally, this middleware made use of the connect-openui5 proxy implementation (https://github.com/SAP/connect-openui5#proxy).
+
+More sophisticated proxy solutions for ui5-server are already available in the form of custom middleware extensions from the UI5-community.
+
+The UI5 Team might provide a dedicated custom middleware extension, with similar functionality, in the future.
+
+- Server now requires a Project Graph instance instead.
+- Standard middleware now rely on Project instances being available on Resources (see https://github.com/SAP/ui5-fs/pull/381)
+- MiddlewareRepository#addMiddleware has been removed. Custom middleware need to be added to the project graph instead
+
+#### @ui5/fs
+An error is thrown when a resource shall be written to an adapter where the path of the resource does not starts with the virtual base path defined in the adapter.
+
+Resources stored in the adapters can not be modified by reference anymore. All modifications need to be persisted by using the #write method in order to be reflected in the adapter.1d908bbc7ff3ecc99d99c
+
+### @ui5/logger
+The @ui5/logger got refactored and as a result its API went public. Remove the usage of npmlog and refactor @ui5/logger modules to emit log events which are then caught in dedicated handlers. This is somewhat inspired by npm's proc-log module.
+
+This breaking change removes capabilities that are likely to change and should not be part of a public API.
+This will ensure that later changes to the module can be done in a compatible manner.
+
+Relevant changes:
+
+- Restrict log-methods to two argument only. The use of placeholders like '%s' is no longer supported.
+ A warning will be logged if more than two argument is supplied. Placeholders will be replaced with a deprecation message. We suggest the use of template literals.
+- Deprecate #getGroupLogger method. Calling it throws an error.
+ It will be removed in one of the next patch releases
+- Deprecate #setShowProgress method. Calling it throws an error.
+ It will be removed in one of the next patch releases
+- Remove GroupLogger and TaskLogger classes. Similar functionality might be re-added in a later release.
+
+
+
+## [v2.14.17] - 2022-12-13
+
+
+## [v2.14.16] - 2022-11-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.4.0 to 2.4.1 [`92fb840`](https://github.com/SAP/ui5-cli/commit/92fb840f77bf3a8669bee11ed9e22dbef240d1d3)
+
+
+
+## [v2.14.15] - 2022-11-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.8 to 2.11.9 [`803f8cc`](https://github.com/SAP/ui5-cli/commit/803f8ccb9f3daf3523872f9a4bbf0bda5e3c7f02)
+
+
+
+## [v2.14.14] - 2022-10-28
+### Bug Fixes
+- **SyntaxError:** Unexpected token '.' in Node.js v12 [`bab2057`](https://github.com/SAP/ui5-cli/commit/bab2057e184a2072f9b596565d9690b6e39b109d)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.7 to 2.11.8 [`1f5e517`](https://github.com/SAP/ui5-cli/commit/1f5e5173d0ca594ea4a34b97b0a760c67a9664a9)
+
+
+
+## [v2.14.13] - 2022-10-20
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.6 to 2.11.7 [`d3b3f06`](https://github.com/SAP/ui5-cli/commit/d3b3f0626e0c03d999b150338d4112d3c875e02d)
+
+
+
+## [v2.14.12] - 2022-10-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.5 to 2.11.6 [`f695e27`](https://github.com/SAP/ui5-cli/commit/f695e2733395599271b1a1059860c519851c7fe7)
+
+
+
+## [v2.14.11] - 2022-09-05
+### Bug Fixes
+- Upgrade update-notifier to solve security vulnerabilities ([#533](https://github.com/SAP/ui5-cli/issues/533)) [`5b7cfcf`](https://github.com/SAP/ui5-cli/commit/5b7cfcf62c37492c4072c69f400512ef59aab502)
+
+
+
+## [v2.14.10] - 2022-07-25
+
+
+## [v2.14.9] - 2022-05-04
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.4 to 2.11.5 [`aa90039`](https://github.com/SAP/ui5-cli/commit/aa9003933bb6f5e71e9ce968ab5cc6202f805256)
+
+
+
+## [v2.14.8] - 2022-04-14
+
+
+## [v2.14.7] - 2022-03-25
+
+
+## [v2.14.6] - 2022-02-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.3 to 2.11.4 [`f8ce36c`](https://github.com/SAP/ui5-cli/commit/f8ce36ca504c1021c3e3825a6762dda29f7ea74d)
+
+
+
+## [v2.14.5] - 2022-02-17
+
+
+## [v2.14.4] - 2022-01-24
+
+
+## [v2.14.3] - 2022-01-19
+
+
+## [v2.14.2] - 2021-12-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.2 to 2.11.3 [`ebe6377`](https://github.com/SAP/ui5-cli/commit/ebe6377e347475cf2219ea97deee44fd617f6d7e)
+
+
+
+## [v2.14.1] - 2021-11-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.1 to 2.11.2 [`f389b00`](https://github.com/SAP/ui5-cli/commit/f389b00c95ce81ad1993fef2bd7b4ad79d523be1)
+
+
+
+## [v2.14.0] - 2021-10-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.5.0 to 2.6.0 [`2c42bba`](https://github.com/SAP/ui5-cli/commit/2c42bba826add655dd0bf44d4c78ff72258d10b2)
+- Bump [@ui5](https://github.com/ui5)/server from 2.3.1 to 2.4.0 [`063b2f7`](https://github.com/SAP/ui5-cli/commit/063b2f77c936b90f1a2cd9febb7a5aed0f17fa20)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.0 to 2.11.1 [`11a0f5a`](https://github.com/SAP/ui5-cli/commit/11a0f5a391ca9e629b52b3046560678a8afeaf16)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.10.0 to 2.11.0 [`6f13917`](https://github.com/SAP/ui5-cli/commit/6f139171d3bd46da7bdb1c4c8015589e60fa14f6)
+
+
+
+## [v2.13.0] - 2021-10-05
+### Bug Fixes
+- Allow Node.js pre-release versions ([#458](https://github.com/SAP/ui5-cli/issues/458)) [`f6351c6`](https://github.com/SAP/ui5-cli/commit/f6351c663975f4ea14f08fa9a655bb6bf0447080)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.5 to 2.10.0 [`1d6a0f4`](https://github.com/SAP/ui5-cli/commit/1d6a0f423fc3fa782b341614d562c04292f00e1b)
+
+
+
+## [v2.12.1] - 2021-08-25
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.4 to 2.9.5 [`e25a630`](https://github.com/SAP/ui5-cli/commit/e25a630b03d0d68566b200e1346e25ed77f34c44)
+
+
+
+## [v2.12.0] - 2021-07-23
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.4.0 to 2.5.0 [`0b4c2fb`](https://github.com/SAP/ui5-cli/commit/0b4c2fbc840024e30c1f85de441c5908a4774518)
+- Bump [@ui5](https://github.com/ui5)/server from 2.3.0 to 2.3.1 [`ffbd9a5`](https://github.com/SAP/ui5-cli/commit/ffbd9a5bc0e9ac0d3dca4f66d0ab5a7758aaec3a)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.3 to 2.9.4 [`dfeb74e`](https://github.com/SAP/ui5-cli/commit/dfeb74ec96a5c14a500d56952f4727b1b7f0b4cd)
+
+### Features
+- Support to only build certain dependencies ([#442](https://github.com/SAP/ui5-cli/issues/442)) [`5f941f1`](https://github.com/SAP/ui5-cli/commit/5f941f1e5d3041fc94f2e9e9eed14ad44add78aa)
+
+
+
+## [v2.11.3] - 2021-07-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.10 to 2.3.0 [`1d852fc`](https://github.com/SAP/ui5-cli/commit/1d852fc5e455934fc533c99c5fa62346b33c7182)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.2 to 2.9.3 [`73036be`](https://github.com/SAP/ui5-cli/commit/73036be811572ba50c439ccc95b15110057a6a62)
+
+
+
+## [v2.11.2] - 2021-06-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.1 to 2.9.2 [`be6c9a4`](https://github.com/SAP/ui5-cli/commit/be6c9a456986f123a2e0da2d3b5b3b9d1bbf962a)
+
+
+
+## [v2.11.1] - 2021-06-08
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.0 to 2.9.1 [`a2a66d8`](https://github.com/SAP/ui5-cli/commit/a2a66d872b3b9c309e3ad9664a94a24577836296)
+
+
+
+## [v2.11.0] - 2021-06-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.3.1 to 2.4.0 [`f50642a`](https://github.com/SAP/ui5-cli/commit/f50642aebe9e99b958dc29048769a627c170552d)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.9 to 2.2.10 [`8670767`](https://github.com/SAP/ui5-cli/commit/86707676c179622f1b6b1b523cb29292be3dbdac)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.4 to 2.9.0 [`9e3b7ec`](https://github.com/SAP/ui5-cli/commit/9e3b7ecb033cd45b30ba7b8645cb97c19e2a34e8)
+
+
+
+## [v2.10.4] - 2021-05-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.3 to 2.8.4 [`7df37c1`](https://github.com/SAP/ui5-cli/commit/7df37c11d3c8194b282d9972345c8b844427ff12)
+
+
+
+## [v2.10.3] - 2021-04-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.2 to 2.8.3 [`572bac4`](https://github.com/SAP/ui5-cli/commit/572bac4a147d2e87bab9a57858637f34ef03a1ce)
+
+
+
+## [v2.10.2] - 2021-03-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.8 to 2.2.9 [`a7d3436`](https://github.com/SAP/ui5-cli/commit/a7d343696f059389709085df831f3c7f9afc8898)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.1 to 2.8.2 [`6d308da`](https://github.com/SAP/ui5-cli/commit/6d308da757dcc1d975475677b42520ab146116d0)
+
+
+
+## [v2.10.1] - 2021-03-04
+### Bug Fixes
+- `ui5 use ` should default to `latest` [`cda4b2c`](https://github.com/SAP/ui5-cli/commit/cda4b2cc29e376d92be4bc92fb7ee2a81974836a)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.3.0 to 2.3.1 [`912c6e0`](https://github.com/SAP/ui5-cli/commit/912c6e0c37e2df4a8768c0b6879aff58703d303a)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.0 to 2.8.1 [`baed42f`](https://github.com/SAP/ui5-cli/commit/baed42f282ec1e3cf6d42a8fed97fe81844ad8c5)
+- Bump js-yaml from 3.14.1 to 4.0.0 ([#402](https://github.com/SAP/ui5-cli/issues/402)) [`0033c52`](https://github.com/SAP/ui5-cli/commit/0033c5272b6258c95cc1f7487aa53c7e64bbe50c)
+
+
+
+## [v2.10.0] - 2021-02-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.6 to 2.3.0 [`e8c5f37`](https://github.com/SAP/ui5-cli/commit/e8c5f3781d6a7ed649ff68481eccf4f3cf4a1990)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.7 to 2.2.8 [`8325bdf`](https://github.com/SAP/ui5-cli/commit/8325bdf698d28143f1d989139f162fc57217f939)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.7.2 to 2.8.0 [`553d543`](https://github.com/SAP/ui5-cli/commit/553d5432599fa18bed7fb878856f78f294460e46)
+
+
+
+## [v2.9.3] - 2021-01-29
+
+
+## [v2.9.2] - 2021-01-29
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.7.1 to 2.7.2 [`0d0e9e9`](https://github.com/SAP/ui5-cli/commit/0d0e9e94dce8168944d2833d44073ac79318cdc5)
+
+
+
+## [v2.9.1] - 2021-01-28
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.5 to 2.2.6 [`7a6182a`](https://github.com/SAP/ui5-cli/commit/7a6182a4fe23475b074e7bec9c6feaeb08534670)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.7.0 to 2.7.1 [`9e2882e`](https://github.com/SAP/ui5-cli/commit/9e2882eca7179389227da731682bf1c9c0425617)
+
+
+
+## [v2.9.0] - 2021-01-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.6.1 to 2.7.0 [`d9f00fc`](https://github.com/SAP/ui5-cli/commit/d9f00fc68ed032be6ef614811aceccea9a947a2e)
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.4 to 2.2.5 [`62886ce`](https://github.com/SAP/ui5-cli/commit/62886ce921479a7198d658b296b66fe040cc89d9)
+
+
+
+## [v2.8.1] - 2021-01-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.6.0 to 2.6.1 [`d2d1081`](https://github.com/SAP/ui5-cli/commit/d2d1081da16b18c1a4ec78c1e09f6568f53f3c61)
+
+
+
+## [v2.8.0] - 2021-01-14
+### Bug Fixes
+- **ui5 use:** Corrupt UI5 configuration [`c207e1e`](https://github.com/SAP/ui5-cli/commit/c207e1e7318123a8801627ca80e61f59e7c73edb)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.5.1 to 2.6.0 [`711a071`](https://github.com/SAP/ui5-cli/commit/711a07120b9ed652674216f22d81c8098d790a95)
+
+
+
+## [v2.7.1] - 2020-12-18
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.5.0 to 2.5.1 [`9a208c1`](https://github.com/SAP/ui5-cli/commit/9a208c173f005178f41e343e67c61c021de71f61)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.5 to 2.0.6 [`3965d14`](https://github.com/SAP/ui5-cli/commit/3965d1442ad2e11d26f6730fdb8ff6ec7fff0172)
+
+
+
+## [v2.7.0] - 2020-12-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.5 to 2.5.0 [`9c353a6`](https://github.com/SAP/ui5-cli/commit/9c353a6327f11f016c7bd18da76b3468eca42fc6)
+
+
+
+## [v2.6.6] - 2020-11-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.4 to 2.4.5 [`10c0342`](https://github.com/SAP/ui5-cli/commit/10c03428cd0108a1c380de4abff45af1ce97ef55)
+
+
+
+## [v2.6.5] - 2020-11-25
+### Bug Fixes
+- Always log stack trace of unexpected errors [`aba4e49`](https://github.com/SAP/ui5-cli/commit/aba4e493fd5609cf17e820651be0336a7c7b3390)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.3 to 2.4.4 [`9935fed`](https://github.com/SAP/ui5-cli/commit/9935fed156f4367160b6dd9d3b2beecf1d23710b)
+
+
+
+## [v2.6.4] - 2020-11-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.6 to 2.2.7 [`bc83eac`](https://github.com/SAP/ui5-cli/commit/bc83eac65618a5cad889cea9c7518cacf9022b1e)
+
+
+
+## [v2.6.3] - 2020-11-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.3 to 2.2.4 [`7b69c21`](https://github.com/SAP/ui5-cli/commit/7b69c216f9eb5a9621ee9934e6e7224365111fe6)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.2 to 2.4.3 [`898f7de`](https://github.com/SAP/ui5-cli/commit/898f7de99e4f60067759d04818f10ea6ac544b5f)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.4 to 2.0.5 [`8281b8b`](https://github.com/SAP/ui5-cli/commit/8281b8bde7ed7175e340ca7af0b2bdb3276b0310)
+
+### Performance Improvements
+- Reduce install size by removing 'string.prototype.matchall' dependency [`cb34e84`](https://github.com/SAP/ui5-cli/commit/cb34e84db1a6212c37ca56f8fb3fa86bc496deab)
+
+
+
+## [v2.6.2] - 2020-11-04
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.1 to 2.4.2 [`60126af`](https://github.com/SAP/ui5-cli/commit/60126af947665b470b7dd2245feab0fa05ed78b6)
+
+
+
+## [v2.6.1] - 2020-11-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.0 to 2.4.1 [`e22e372`](https://github.com/SAP/ui5-cli/commit/e22e372119688d7b8a5862a8c2d5c166e85b3e92)
+
+
+
+## [v2.6.0] - 2020-11-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.3.0 to 2.4.0 [`2d49e9b`](https://github.com/SAP/ui5-cli/commit/2d49e9be5706d2ff0ae74587d0d91f3d1dcd2ebe)
+
+
+
+## [v2.5.0] - 2020-10-22
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.2 to 2.2.3 [`21f5bd6`](https://github.com/SAP/ui5-cli/commit/21f5bd6c7d478dd143184dcdd9b1097831c7c3c7)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.5 to 2.2.6 [`6740a0c`](https://github.com/SAP/ui5-cli/commit/6740a0c424e00a3be23fb8aeb1e1570f9aa53b67)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.2.1 to 2.3.0 [`8574924`](https://github.com/SAP/ui5-cli/commit/8574924c1b8e434aff0fa42c0a66f4ef2275fc97)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.3 to 2.0.4 [`3c14bd4`](https://github.com/SAP/ui5-cli/commit/3c14bd403b1c48da32b5e1ae8a9dcbf3da12f7b8)
+- Bump [@ui5](https://github.com/ui5)/logger from 2.0.0 to 2.0.1 [`a401bfd`](https://github.com/SAP/ui5-cli/commit/a401bfd768412453148323f19e8f773cb367ee96)
+
+
+
+## [v2.4.5] - 2020-10-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.4 to 2.2.5 [`80edb1c`](https://github.com/SAP/ui5-cli/commit/80edb1c403025ee2d3a3542c3d1c6530cebb6832)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.2.0 to 2.2.1 [`f464793`](https://github.com/SAP/ui5-cli/commit/f4647938ee327dcebda9eafaf318c0296d6a0d4a)
+
+
+
+## [v2.4.4] - 2020-09-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.1 to 2.2.2 [`3755911`](https://github.com/SAP/ui5-cli/commit/3755911b0b6818129079cf138409a3827f1d2c29)
+
+
+
+## [v2.4.3] - 2020-09-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.3 to 2.2.4 [`1d033a4`](https://github.com/SAP/ui5-cli/commit/1d033a4ab519e688dac18aa2dc2888b8695254aa)
+
+
+
+## [v2.4.2] - 2020-09-02
+### Bug Fixes
+- Allow use of `--no-update-notifier` flag [`a34b58c`](https://github.com/SAP/ui5-cli/commit/a34b58c260ecb3778eb737d983b4d6b0a5829511)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.0 to 2.2.1 [`1f735d9`](https://github.com/SAP/ui5-cli/commit/1f735d922de587ed7a876eb44db4aa32dd2dad86)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.2 to 2.2.3 [`5170730`](https://github.com/SAP/ui5-cli/commit/5170730fa1e3b1275856a9e7346def42257d012a)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.1.0 to 2.2.0 [`b164a69`](https://github.com/SAP/ui5-cli/commit/b164a69a8df5b3270dc06755c1e2b3f59f715689)
+
+
+
+## [v2.4.1] - 2020-08-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.2 to 2.0.3 [`2189686`](https://github.com/SAP/ui5-cli/commit/218968643d646443815e9e1206c40aac7edd3e2f)
+
+
+
+## [v2.4.0] - 2020-08-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.5 to 2.2.0 [`43cc824`](https://github.com/SAP/ui5-cli/commit/43cc82473e02c714586047b0a453ba8d1d0a3818)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.1 to 2.2.2 [`42f4acc`](https://github.com/SAP/ui5-cli/commit/42f4acc8545cb8a5c6db62dc1a26ba09229157e0)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.7 to 2.1.0 [`30cfbc6`](https://github.com/SAP/ui5-cli/commit/30cfbc672c62aba9ef3561336ac2bf1d5e6a470a)
+
+
+
+## [v2.3.2] - 2020-08-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.6 to 2.0.7 [`fba5633`](https://github.com/SAP/ui5-cli/commit/fba56332a2a8395da2459dec40f81e04ca80dd9f)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.1 to 2.0.2 [`d584699`](https://github.com/SAP/ui5-cli/commit/d584699855fc44d59ff67cc5720dda3733f3cc13)
+
+
+
+## [v2.3.1] - 2020-07-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.5 to 2.0.6 [`12dd9f6`](https://github.com/SAP/ui5-cli/commit/12dd9f6fc2d844a9425c6baf2822ac5b956a571e)
+
+
+
+## [v2.3.0] - 2020-07-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.4 to 2.1.5 [`0740fd1`](https://github.com/SAP/ui5-cli/commit/0740fd19d8530478820d5638db4e5eb0170b9ac1)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.0 to 2.2.1 [`139b59a`](https://github.com/SAP/ui5-cli/commit/139b59a3237bf66e8a851fbcf51d6a20b48dcc10)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.4 to 2.0.5 [`4c28263`](https://github.com/SAP/ui5-cli/commit/4c2826320ff8ac9af34fa417121f2cdcacb042aa)
+- Bump [@ui5](https://github.com/ui5)/server from 2.1.0 to 2.2.0 [`b5bf1cb`](https://github.com/SAP/ui5-cli/commit/b5bf1cb8e73dc563ffb42397cfa679b5d97202ee)
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.3 to 2.1.0 [`bd26b2b`](https://github.com/SAP/ui5-cli/commit/bd26b2bb5ed2824a1d0be1c8a18ffa17f4e4af22)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.3 to 2.0.4 [`a20233e`](https://github.com/SAP/ui5-cli/commit/a20233ea8f88bf41b09990c53a3911c558e62dfa)
+
+### Features
+- **ui5 serve:** Add serve-csp-reports option ([#339](https://github.com/SAP/ui5-cli/issues/339)) [`063e7a5`](https://github.com/SAP/ui5-cli/commit/063e7a512d474353e2d86dd77453b10935b4bc05)
+
+
+
+## [v2.2.6] - 2020-05-29
+### Bug Fixes
+- **ui5 use:** Allow using versions according to Semantic Versioning [`d7a9363`](https://github.com/SAP/ui5-cli/commit/d7a9363ac10f167b7e5ebc1c5a7384f0fc6abbcc)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.3 to 2.1.4 [`c584f11`](https://github.com/SAP/ui5-cli/commit/c584f114b7b8ba936399360832296e62e485977c)
+
+
+
+## [v2.2.5] - 2020-05-27
+
+
+## [v2.2.4] - 2020-05-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.2 to 2.0.3 [`b0ef029`](https://github.com/SAP/ui5-cli/commit/b0ef0291cdc64ddbb1cb459fff4582f7c0db326e)
+
+
+
+## [v2.2.3] - 2020-05-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.2 to 2.1.3 [`e58febb`](https://github.com/SAP/ui5-cli/commit/e58febb866a6413407723608b9049be78afaa1ef)
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.2 to 2.0.3 [`a73b7e3`](https://github.com/SAP/ui5-cli/commit/a73b7e3af01a488f5c9e7c7b68211ca2a8cda3e8)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.1 to 2.0.2 [`2c53f21`](https://github.com/SAP/ui5-cli/commit/2c53f21dc83531645f67a08182b83b5042f4cc30)
+
+
+
+## [v2.2.2] - 2020-05-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.1 to 2.1.2 [`191e621`](https://github.com/SAP/ui5-cli/commit/191e6211b5ff9e4edb8c32f71d7509e9e755e596)
+
+
+
+## [v2.2.1] - 2020-05-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.0 to 2.1.1 [`14a19d9`](https://github.com/SAP/ui5-cli/commit/14a19d98bd35635b87ada4c58cd79fe44f3c5a67)
+
+
+
+## [v2.2.0] - 2020-05-05
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.4 to 2.1.0 [`dce7fd2`](https://github.com/SAP/ui5-cli/commit/dce7fd2f00731d9fac016695cf7775692cdf6cd9)
+
+
+
+## [v2.1.0] - 2020-04-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.3 to 2.0.4 [`0bee0a0`](https://github.com/SAP/ui5-cli/commit/0bee0a0a818168263d925b49af3d8008f1c66cc3)
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.1 to 2.0.2 [`f7ed0cc`](https://github.com/SAP/ui5-cli/commit/f7ed0ccee6cc20b0a4c2aade78a89ffcacc267e1)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.0 to 2.0.1 [`e70a426`](https://github.com/SAP/ui5-cli/commit/e70a42692c755317f6f7e612725550ef834e4d07)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.0 to 2.0.1 [`3b50590`](https://github.com/SAP/ui5-cli/commit/3b5059055b1dcc69d42b128cccdc3251c7c24b49)
+
+### Features
+- Add "ui5 remove" command ([#327](https://github.com/SAP/ui5-cli/issues/327)) [`6c6be0d`](https://github.com/SAP/ui5-cli/commit/6c6be0d3941507c965dd303f3964f4cf5a77731c)
+
+
+
+## [v2.0.3] - 2020-04-15
+### Bug Fixes
+- **ui5 use/add:** Fix updating ui5.yaml file [`225f4ab`](https://github.com/SAP/ui5-cli/commit/225f4aba7c60439c4f3d7554cb918a2ba03ce1bd)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.0 to 2.0.1 [`2d81aa8`](https://github.com/SAP/ui5-cli/commit/2d81aa814f9008e6cf4e38a5d5a9ca2d2d00623a)
+
+
+
+## [v2.0.2] - 2020-04-02
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.2 to 2.0.3 [`1aaa9c1`](https://github.com/SAP/ui5-cli/commit/1aaa9c19a1b3a90e9df27f27f8c9b0f160902945)
+
+
+
+## [v2.0.1] - 2020-04-01
+### Bug Fixes
+- **npm-shrinkwrap.json:** Add additional dependencies [`a6c88f7`](https://github.com/SAP/ui5-cli/commit/a6c88f79a297602d579dd68a136c571809152582)
+
+
+
+## [v2.0.0] - 2020-04-01
+### Breaking Changes
+- Require Node.js >= 10 [`e0916ec`](https://github.com/SAP/ui5-cli/commit/e0916ec85315f6370af1b6fbc4ba5ff99f9c2c49)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.1 to 2.0.2 [`7539675`](https://github.com/SAP/ui5-cli/commit/7539675648581f3c36b21da67a1c4da12a10c763)
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.0 to 2.0.1 [`2f8fbe1`](https://github.com/SAP/ui5-cli/commit/2f8fbe1b5390f6f90bf76ad107ee3f7547a7519d)
+- Bump [@ui5](https://github.com/ui5)/project from 1.2.0 to 2.0.0 [`f18f07c`](https://github.com/SAP/ui5-cli/commit/f18f07cc11f54fb936b582460d4b3ef8a844111a)
+- Bump [@ui5](https://github.com/ui5)/server from 1.6.0 to 2.0.0 [`f514cc5`](https://github.com/SAP/ui5-cli/commit/f514cc538760b6ee7a54220a2556acc8a89434b0)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.10.1 to 2.0.0 [`eee43a6`](https://github.com/SAP/ui5-cli/commit/eee43a64f6b8523ffb381a47cafc416f9152d989)
+- Bump [@ui5](https://github.com/ui5)/fs from 1.1.2 to 2.0.0 [`68f69b7`](https://github.com/SAP/ui5-cli/commit/68f69b74dd2d8edcf1d145f7d7e9398136b537f4)
+- Bump [@ui5](https://github.com/ui5)/logger from 1.0.2 to 2.0.0 [`847193d`](https://github.com/SAP/ui5-cli/commit/847193d8a56c9401dfd680fe84fd99747b349ce9)
+
+### Features
+- Add "ui5 use/add" commands ([#315](https://github.com/SAP/ui5-cli/issues/315)) [`920fbfc`](https://github.com/SAP/ui5-cli/commit/920fbfc5ea27f689aeb38beb6540c41838225c8d)
+- Add --framework-version option ([#306](https://github.com/SAP/ui5-cli/issues/306)) [`ae7932b`](https://github.com/SAP/ui5-cli/commit/ae7932bb36b68f3836df285ab0040083ed914c2f)
+
+### BREAKING CHANGE
+
+Support for older Node.js releases has been dropped.
+Only Node.js v10 or higher is supported.
+
+
+
+## [v1.14.0] - 2020-02-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.4 to 1.6.0 [`ece1295`](https://github.com/SAP/ui5-cli/commit/ece1295083e6530701b63a0c77f475d40700e998)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.10.0 to 1.10.1 [`fadd1ee`](https://github.com/SAP/ui5-cli/commit/fadd1ee5ade74aa236f6f8671bca8ca0b934e697)
+
+
+
+## [v1.13.1] - 2020-01-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.2 to 1.5.3 [`4e43b04`](https://github.com/SAP/ui5-cli/commit/4e43b04732ae236fb14d3e55afd95e9f229581d0)
+
+
+
+## [v1.13.0] - 2020-01-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.1.1 to 1.2.0 [`af1b153`](https://github.com/SAP/ui5-cli/commit/af1b153506e5a668178d227ea9686a266675bb64)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.8.0 to 1.9.0 [`166d247`](https://github.com/SAP/ui5-cli/commit/166d247fb94f4394a4fa33afe4ad6d75cbee58f4)
+
+
+
+## [v1.12.2] - 2019-12-16
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.1 to 1.5.2 [`4ef70a7`](https://github.com/SAP/ui5-cli/commit/4ef70a78f97bd2472858cd08cfdf8814cb48256f)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.7.1 to 1.8.0 [`4d0cd36`](https://github.com/SAP/ui5-cli/commit/4d0cd36e44a887d41f418e7b784c363b024a5def)
+
+
+
+## [v1.12.1] - 2019-11-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.0 to 1.5.1 [`7a07a2e`](https://github.com/SAP/ui5-cli/commit/7a07a2e4fe7491295c2228e53da30d0e7051b962)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.7.0 to 1.7.1 [`ecbfad1`](https://github.com/SAP/ui5-cli/commit/ecbfad1afdf726b76bef09c4e604d91e1eb7690d)
+
+
+
+## [v1.12.0] - 2019-11-07
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.1.0 to 1.1.1 [`abca385`](https://github.com/SAP/ui5-cli/commit/abca38566c5728f896d5be880fcb24f795b0b11c)
+- Bump [@ui5](https://github.com/ui5)/server from 1.4.0 to 1.5.0 [`abf954b`](https://github.com/SAP/ui5-cli/commit/abf954b2b1224353b5c7a09b37394fc53562cbfc)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.6.1 to 1.7.0 [`f482702`](https://github.com/SAP/ui5-cli/commit/f482702f8a941f2c17490d67a74ac97486dce811)
+
+### Features
+- **serve:** Add '--simple-index' parameter ([#265](https://github.com/SAP/ui5-cli/issues/265)) [`dbe195e`](https://github.com/SAP/ui5-cli/commit/dbe195e8c81a8e4e7ab2c0b8d08ba6890dd5311d)
+
+
+
+## [v1.11.1] - 2019-10-30
+### Bug Fixes
+- Fix 'ui5 tree' output [`a64de74`](https://github.com/SAP/ui5-cli/commit/a64de744eec019094d11dec491f73cfac923a541)
+
+
+
+## [v1.11.0] - 2019-10-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.3.0 to 1.4.0 [`07f4719`](https://github.com/SAP/ui5-cli/commit/07f4719d488ba96800860fd780a9e08f6902ccb8)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.3 to 1.6.1 [`6d46c54`](https://github.com/SAP/ui5-cli/commit/6d46c545b3d9c347d2f6501f962acdb6d67761cc)
+- Bump [@ui5](https://github.com/ui5)/logger from 1.0.1 to 1.0.2 [`0394f1a`](https://github.com/SAP/ui5-cli/commit/0394f1afcbb8b653647834dce0c20a3e874eaeb9)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.2 to 1.5.3 [`0eee47f`](https://github.com/SAP/ui5-cli/commit/0eee47f273d8a9b5465659647319bf003ffa0399)
+
+### Features
+- **CLI:** Improve error reporting [`160b8f7`](https://github.com/SAP/ui5-cli/commit/160b8f76b70b50d3e03494ef98e140e1ef8c4d8c)
+
+
+
+## [v1.10.0] - 2019-10-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.1 to 1.5.2 [`cf2f4a9`](https://github.com/SAP/ui5-cli/commit/cf2f4a9dc813fe8452820b484b4abae79ee5f342)
+
+### Features
+- Add server settings [`3638ed7`](https://github.com/SAP/ui5-cli/commit/3638ed71411d0c2882a8a145113a484d16eff56b)
+
+
+
+## [v1.9.0] - 2019-09-05
+### Features
+- **ui5 build:** Add --clean-dest option [`fe60d04`](https://github.com/SAP/ui5-cli/commit/fe60d041c374494c58136435d7761e8ee957ce7b)
+
+
+
+## [v1.8.1] - 2019-09-04
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.0 to 1.5.1 [`1346031`](https://github.com/SAP/ui5-cli/commit/13460317cf32afc8122486d6b086bb1e61451b99)
+
+
+
+## [v1.8.0] - 2019-09-02
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.4.2 to 1.5.0 [`3de07b2`](https://github.com/SAP/ui5-cli/commit/3de07b2a9c7b804519de3680dba2e80198cfbc62)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.4.1 to 1.4.2 [`f2d1ff0`](https://github.com/SAP/ui5-cli/commit/f2d1ff0d98da460c564450ccb8a70bde094bc229)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.4.0 to 1.4.1 [`e5dcc5f`](https://github.com/SAP/ui5-cli/commit/e5dcc5fe797148008e96aabdb7e9d5eead65fefc)
+
+
+
+## [v1.7.0] - 2019-08-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.2.0 to 1.3.0 [`c4db860`](https://github.com/SAP/ui5-cli/commit/c4db8607130efdbecece47938a6d81f917681a91)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.3 to 1.4.0 [`cfbb26b`](https://github.com/SAP/ui5-cli/commit/cfbb26b00cb01c8a1bf211e7e81f902163d9600f)
+
+### Features
+- Log CLI version when using --verbose option [`c143a85`](https://github.com/SAP/ui5-cli/commit/c143a85d615f7e493b2bcaa98422707e3cf49e5b)
+
+
+
+## [v1.6.0] - 2019-07-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.3 to 1.1.0 [`659f31e`](https://github.com/SAP/ui5-cli/commit/659f31e42880a2367a79cae5ca4aee2f03d3f227)
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.3 to 1.2.0 [`ce69e24`](https://github.com/SAP/ui5-cli/commit/ce69e2434963dbacc4d4e834c4e00ecfaa89e9a6)
+
+
+
+## [v1.5.5] - 2019-07-01
+### Bug Fixes
+- **serve:** Create SSL certificate in user homedir [`48bdd06`](https://github.com/SAP/ui5-cli/commit/48bdd06bfcec3063ba046b37be76c80139458779)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.2 to 1.3.3 [`43d4fd7`](https://github.com/SAP/ui5-cli/commit/43d4fd7c634e869de985ea48c4f77d25c9bc53bc)
+- Bump [@ui5](https://github.com/ui5)/fs from 1.1.1 to 1.1.2 [`5a0ece1`](https://github.com/SAP/ui5-cli/commit/5a0ece130af8164befa9e84d4494d69704cb5c0e)
+
+
+
+## [v1.5.4] - 2019-06-25
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.2 to 1.0.3 [`3b0a8f7`](https://github.com/SAP/ui5-cli/commit/3b0a8f7b96de5621e3b72c9ced579104e8750464)
+
+
+
+## [v1.5.3] - 2019-06-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.2 to 1.1.3 [`4dc552f`](https://github.com/SAP/ui5-cli/commit/4dc552fc84e79b3c4b2b4d6e6a08426b334b430c)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.1 to 1.3.2 [`98f17f1`](https://github.com/SAP/ui5-cli/commit/98f17f1c4d9d993ddbfb9195f46172fc4f777296)
+
+
+
+## [v1.5.2] - 2019-06-18
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/fs from 1.1.0 to 1.1.1 [`fd5f550`](https://github.com/SAP/ui5-cli/commit/fd5f55064c1600dd92070c7ed82ab6a0c0539d57)
+
+
+
+## [v1.5.1] - 2019-06-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.0 to 1.3.1 [`d1c8814`](https://github.com/SAP/ui5-cli/commit/d1c8814a577d9065e070022c1bb03417cde2b8bc)
+
+
+
+## [v1.5.0] - 2019-06-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.1 to 1.1.2 [`1d54bd5`](https://github.com/SAP/ui5-cli/commit/1d54bd53cf8bd24b5df30328a267c0ef3c8b110a)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.3 to 1.3.0 [`82ef6c1`](https://github.com/SAP/ui5-cli/commit/82ef6c10f92648e76da8855b1777df39df535805)
+- Bump [@ui5](https://github.com/ui5)/fs from 1.0.2 to 1.1.0 [`3f0ce7d`](https://github.com/SAP/ui5-cli/commit/3f0ce7d6cd9dbf1cbb6b38a9a55fdd47bf45383a)
+
+
+
+## [v1.4.4] - 2019-05-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.2 to 1.2.3 [`1f8e911`](https://github.com/SAP/ui5-cli/commit/1f8e9114db3701bac071d09477837940ccba0cad)
+
+
+
+## [v1.4.3] - 2019-05-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.0 to 1.1.1 [`7e81541`](https://github.com/SAP/ui5-cli/commit/7e81541e89487acec7f57ec4ac89d181486b4909)
+
+
+
+## [v1.4.2] - 2019-05-08
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.1 to 1.2.2 [`88a1f83`](https://github.com/SAP/ui5-cli/commit/88a1f83a37e5795067687bf5cabb77bceca96e61)
+
+
+
+## [v1.4.1] - 2019-05-07
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.0 to 1.2.1 [`3c03878`](https://github.com/SAP/ui5-cli/commit/3c038784b263b1d1af2c47802eea7c1b48c9baae)
+
+
+
+## [v1.4.0] - 2019-04-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.0.0 to 1.1.0 [`fe03e1e`](https://github.com/SAP/ui5-cli/commit/fe03e1ec034698f213649526482c2a05c2132c92)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.1.1 to 1.2.0 [`b4747fb`](https://github.com/SAP/ui5-cli/commit/b4747fbefdab4e13173dee054bfd7b66134c65eb)
+
+### Features
+- Add 'sap-csp-policies' option to 'serve' command. ([#188](https://github.com/SAP/ui5-cli/issues/188)) [`57d5567`](https://github.com/SAP/ui5-cli/commit/57d5567b2e78a6d5ce8bbc6cae50b5d7bec80da4)
+
+
+
+## [v1.3.1] - 2019-04-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.1.0 to 1.1.1 [`57d10d4`](https://github.com/SAP/ui5-cli/commit/57d10d40c194b34d2eb1eb22ed820579f1ac097b)
+
+
+
+## [v1.3.0] - 2019-04-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.1 to 1.0.2 [`50a9b5a`](https://github.com/SAP/ui5-cli/commit/50a9b5afc19e0a79f2e1f27c3bcb8f6bd6c34c37)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.5 to 1.1.0 [`f2fe60e`](https://github.com/SAP/ui5-cli/commit/f2fe60e3913cfe4cc9058c90ee1443cdf177425d)
+
+
+
+## [v1.2.4] - 2019-04-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.4 to 1.0.5 [`5787d54`](https://github.com/SAP/ui5-cli/commit/5787d54a048178279de0e253332cfa845655559c)
+
+
+
+## [v1.2.3] - 2019-03-28
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.3 to 1.0.4 ([#181](https://github.com/SAP/ui5-cli/issues/181)) [`ec43aec`](https://github.com/SAP/ui5-cli/commit/ec43aec8e7677b1e45f0a06f58bb29b3766f6f04)
+
+
+
+## [v1.2.2] - 2019-03-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/fs from 1.0.1 to 1.0.2 ([#173](https://github.com/SAP/ui5-cli/issues/173)) [`1f70ee7`](https://github.com/SAP/ui5-cli/commit/1f70ee78a398004549bdc136371c66569ab55849)
+
+### Features
+- **Build:** Add 'jsdoc' command [`3a2f4a1`](https://github.com/SAP/ui5-cli/commit/3a2f4a16fb933429318fd34afd38ab8d9394d80c)
+
+
+
+## [v1.2.1] - 2019-02-28
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.1 to 1.0.2 ([#155](https://github.com/SAP/ui5-cli/issues/155)) [`0b3ac48`](https://github.com/SAP/ui5-cli/commit/0b3ac485cccb5833b69daf8d55f9507106d272b0)
+
+
+
+## [v1.2.0] - 2019-02-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.0 to 1.0.1 ([#142](https://github.com/SAP/ui5-cli/issues/142)) [`c777997`](https://github.com/SAP/ui5-cli/commit/c777997034d84a8a972dbc35638df07c5f1c8c2d)
+- **Security:** Bump handlebars from 4.0.12 to 4.1.0 ([#139](https://github.com/SAP/ui5-cli/issues/139)) [`ec081b6`](https://github.com/SAP/ui5-cli/commit/ec081b61df118921cbe4f050a42cc4ecaf6596c6)
+
+### Features
+- **ui5 tree:** Add dedupe option [`91580a8`](https://github.com/SAP/ui5-cli/commit/91580a8e786a1f63365bd70617403281d5c4c8e3)
+
+
+
+## [v1.1.0] - 2019-02-05
+### Features
+- Publish npm-shrinkwrap.json [`abc5d5e`](https://github.com/SAP/ui5-cli/commit/abc5d5e322696c607adecb20a70d46542862d8ee)
+
+
+
+## [v1.0.1] - 2019-02-01
+### Dependency Updates
+- Add direct dependency to [@ui5](https://github.com/ui5)/fs [`b3eb422`](https://github.com/SAP/ui5-cli/commit/b3eb422300eac59d130548c4ee0025872adb0ce4)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.0 to 1.0.1 ([#131](https://github.com/SAP/ui5-cli/issues/131)) [`46bae7b`](https://github.com/SAP/ui5-cli/commit/46bae7bdef2e500bf4e9953cc8cd13816edb553f)
+
+
+
+## [v1.0.0] - 2019-01-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 0.2.2 to 1.0.0 ([#117](https://github.com/SAP/ui5-cli/issues/117)) [`a3c97b4`](https://github.com/SAP/ui5-cli/commit/a3c97b459aecdc9e6afb829dc380945ec221ede6)
+- Bump [@ui5](https://github.com/ui5)/builder from 0.2.9 to 1.0.0 ([#115](https://github.com/SAP/ui5-cli/issues/115)) [`b979899`](https://github.com/SAP/ui5-cli/commit/b9798990f9806c13405bc1e919e4c6a82db5e855)
+- Bump [@ui5](https://github.com/ui5)/logger from 0.2.2 to 1.0.0 ([#114](https://github.com/SAP/ui5-cli/issues/114)) [`6df410e`](https://github.com/SAP/ui5-cli/commit/6df410e808477b3b7cdbed0b2f0590fa1ece17a2)
+
+### Features
+- **ui5 init:** Use specVersion: '1.0' [`d0bfe7e`](https://github.com/SAP/ui5-cli/commit/d0bfe7ef02d9dde50ed32abb9e6e70375d3263fc)
+
+
+
+## [v0.2.9] - 2019-01-03
+
+
+## [v0.2.8] - 2018-12-19
+
+
+## [v0.2.7] - 2018-12-06
+
+
+## [v0.2.6] - 2018-11-20
+
+
+## [v0.2.5] - 2018-11-20
+### Features
+- Versions Command [`6c75777`](https://github.com/SAP/ui5-cli/commit/6c75777e9ac686d3488cafc5627842810be3afd4)
+
+
+
+## [v0.2.4] - 2018-11-17
+### Features
+- Prefer local over global CLI version ([#59](https://github.com/SAP/ui5-cli/issues/59)) [`3c2a0a8`](https://github.com/SAP/ui5-cli/commit/3c2a0a898742a118206b1009188a7d4933fe8a89)
+
+
+
+## [v0.2.3] - 2018-10-29
+
+
+## [v0.2.2] - 2018-10-10
+
+
+## [v0.2.1] - 2018-07-17
+
+
+## [v0.2.0] - 2018-07-12
+### Features
+- Add Node.js version check [`80b5bfe`](https://github.com/SAP/ui5-cli/commit/80b5bfe1d53494889c794171109321ebbd3f8d61)
+- Add update notifier [`90d03ba`](https://github.com/SAP/ui5-cli/commit/90d03ba8e86f9925b8a9c45cd72ecc28cda75eab)
+
+
+
+## [v0.1.0] - 2018-06-26
+
+
+## [v0.0.2] - 2018-06-21
+
+
+## v0.0.1 - 2018-06-06
+
+
+{{- if .Versions }}
+{{ range .Versions -}}
+{{ if and .Tag.Previous (ne .Tag.Name "v3.0.0") -}}
+[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+[v3.11.1]: https://github.com/SAP/ui5-cli/compare/v3.11.0...v3.11.1
+[v3.11.0]: https://github.com/SAP/ui5-cli/compare/v3.10.3...v3.11.0
+[v3.10.3]: https://github.com/SAP/ui5-cli/compare/v3.10.2...v3.10.3
+[v3.10.2]: https://github.com/SAP/ui5-cli/compare/v3.10.1...v3.10.2
+[v3.10.1]: https://github.com/SAP/ui5-cli/compare/v3.10.0...v3.10.1
+[v3.10.0]: https://github.com/SAP/ui5-cli/compare/v3.9.2...v3.10.0
+[v3.9.2]: https://github.com/SAP/ui5-cli/compare/v3.9.1...v3.9.2
+[v3.9.1]: https://github.com/SAP/ui5-cli/compare/v3.9.0...v3.9.1
+[v3.9.0]: https://github.com/SAP/ui5-cli/compare/v3.8.0...v3.9.0
+[v3.8.0]: https://github.com/SAP/ui5-cli/compare/v3.7.3...v3.8.0
+[v3.7.3]: https://github.com/SAP/ui5-cli/compare/v3.7.2...v3.7.3
+[v3.7.2]: https://github.com/SAP/ui5-cli/compare/v3.7.1...v3.7.2
+[v3.7.1]: https://github.com/SAP/ui5-cli/compare/v3.7.0...v3.7.1
+[v3.7.0]: https://github.com/SAP/ui5-cli/compare/v3.6.1...v3.7.0
+[v3.6.1]: https://github.com/SAP/ui5-cli/compare/v3.6.0...v3.6.1
+[v3.6.0]: https://github.com/SAP/ui5-cli/compare/v3.5.0...v3.6.0
+[v3.5.0]: https://github.com/SAP/ui5-cli/compare/v3.4.1...v3.5.0
+[v3.4.1]: https://github.com/SAP/ui5-cli/compare/v3.4.0...v3.4.1
+[v3.4.0]: https://github.com/SAP/ui5-cli/compare/v3.3.4...v3.4.0
+[v3.3.4]: https://github.com/SAP/ui5-cli/compare/v3.3.3...v3.3.4
+[v3.3.3]: https://github.com/SAP/ui5-cli/compare/v3.3.2...v3.3.3
+[v3.3.2]: https://github.com/SAP/ui5-cli/compare/v3.3.1...v3.3.2
+[v3.3.1]: https://github.com/SAP/ui5-cli/compare/v3.3.0...v3.3.1
+[v3.3.0]: https://github.com/SAP/ui5-cli/compare/v3.2.0...v3.3.0
+[v3.2.0]: https://github.com/SAP/ui5-cli/compare/v3.1.3...v3.2.0
+[v3.1.3]: https://github.com/SAP/ui5-cli/compare/v3.1.2...v3.1.3
+[v3.1.2]: https://github.com/SAP/ui5-cli/compare/v3.1.1...v3.1.2
+[v3.1.1]: https://github.com/SAP/ui5-cli/compare/v3.1.0...v3.1.1
+[v3.1.0]: https://github.com/SAP/ui5-cli/compare/v3.0.7...v3.1.0
+[v3.0.7]: https://github.com/SAP/ui5-cli/compare/v3.0.6...v3.0.7
+[v3.0.6]: https://github.com/SAP/ui5-cli/compare/v3.0.5...v3.0.6
+[v3.0.5]: https://github.com/SAP/ui5-cli/compare/v3.0.4...v3.0.5
+[v3.0.4]: https://github.com/SAP/ui5-cli/compare/v3.0.3...v3.0.4
+[v3.0.3]: https://github.com/SAP/ui5-cli/compare/v3.0.2...v3.0.3
+[v3.0.2]: https://github.com/SAP/ui5-cli/compare/v3.0.1...v3.0.2
+[v3.0.1]: https://github.com/SAP/ui5-cli/compare/v3.0.0...v3.0.1
+[v3.0.0]: https://github.com/SAP/ui5-cli/compare/v2.14.1...v3.0.0
+[v2.14.17]: https://github.com/SAP/ui5-cli/compare/v2.14.16...v2.14.17
+[v2.14.16]: https://github.com/SAP/ui5-cli/compare/v2.14.15...v2.14.16
+[v2.14.15]: https://github.com/SAP/ui5-cli/compare/v2.14.14...v2.14.15
+[v2.14.14]: https://github.com/SAP/ui5-cli/compare/v2.14.13...v2.14.14
+[v2.14.13]: https://github.com/SAP/ui5-cli/compare/v2.14.12...v2.14.13
+[v2.14.12]: https://github.com/SAP/ui5-cli/compare/v2.14.11...v2.14.12
+[v2.14.11]: https://github.com/SAP/ui5-cli/compare/v2.14.10...v2.14.11
+[v2.14.10]: https://github.com/SAP/ui5-cli/compare/v2.14.9...v2.14.10
+[v2.14.9]: https://github.com/SAP/ui5-cli/compare/v2.14.8...v2.14.9
+[v2.14.8]: https://github.com/SAP/ui5-cli/compare/v2.14.7...v2.14.8
+[v2.14.7]: https://github.com/SAP/ui5-cli/compare/v2.14.6...v2.14.7
+[v2.14.6]: https://github.com/SAP/ui5-cli/compare/v2.14.5...v2.14.6
+[v2.14.5]: https://github.com/SAP/ui5-cli/compare/v2.14.4...v2.14.5
+[v2.14.4]: https://github.com/SAP/ui5-cli/compare/v2.14.3...v2.14.4
+[v2.14.3]: https://github.com/SAP/ui5-cli/compare/v2.14.2...v2.14.3
+[v2.14.2]: https://github.com/SAP/ui5-cli/compare/v2.14.1...v2.14.2
+[v2.14.1]: https://github.com/SAP/ui5-cli/compare/v2.14.0...v2.14.1
+[v2.14.0]: https://github.com/SAP/ui5-cli/compare/v2.13.0...v2.14.0
+[v2.13.0]: https://github.com/SAP/ui5-cli/compare/v2.12.1...v2.13.0
+[v2.12.1]: https://github.com/SAP/ui5-cli/compare/v2.12.0...v2.12.1
+[v2.12.0]: https://github.com/SAP/ui5-cli/compare/v2.11.3...v2.12.0
+[v2.11.3]: https://github.com/SAP/ui5-cli/compare/v2.11.2...v2.11.3
+[v2.11.2]: https://github.com/SAP/ui5-cli/compare/v2.11.1...v2.11.2
+[v2.11.1]: https://github.com/SAP/ui5-cli/compare/v2.11.0...v2.11.1
+[v2.11.0]: https://github.com/SAP/ui5-cli/compare/v2.10.4...v2.11.0
+[v2.10.4]: https://github.com/SAP/ui5-cli/compare/v2.10.3...v2.10.4
+[v2.10.3]: https://github.com/SAP/ui5-cli/compare/v2.10.2...v2.10.3
+[v2.10.2]: https://github.com/SAP/ui5-cli/compare/v2.10.1...v2.10.2
+[v2.10.1]: https://github.com/SAP/ui5-cli/compare/v2.10.0...v2.10.1
+[v2.10.0]: https://github.com/SAP/ui5-cli/compare/v2.9.3...v2.10.0
+[v2.9.3]: https://github.com/SAP/ui5-cli/compare/v2.9.2...v2.9.3
+[v2.9.2]: https://github.com/SAP/ui5-cli/compare/v2.9.1...v2.9.2
+[v2.9.1]: https://github.com/SAP/ui5-cli/compare/v2.9.0...v2.9.1
+[v2.9.0]: https://github.com/SAP/ui5-cli/compare/v2.8.1...v2.9.0
+[v2.8.1]: https://github.com/SAP/ui5-cli/compare/v2.8.0...v2.8.1
+[v2.8.0]: https://github.com/SAP/ui5-cli/compare/v2.7.1...v2.8.0
+[v2.7.1]: https://github.com/SAP/ui5-cli/compare/v2.7.0...v2.7.1
+[v2.7.0]: https://github.com/SAP/ui5-cli/compare/v2.6.6...v2.7.0
+[v2.6.6]: https://github.com/SAP/ui5-cli/compare/v2.6.5...v2.6.6
+[v2.6.5]: https://github.com/SAP/ui5-cli/compare/v2.6.4...v2.6.5
+[v2.6.4]: https://github.com/SAP/ui5-cli/compare/v2.6.3...v2.6.4
+[v2.6.3]: https://github.com/SAP/ui5-cli/compare/v2.6.2...v2.6.3
+[v2.6.2]: https://github.com/SAP/ui5-cli/compare/v2.6.1...v2.6.2
+[v2.6.1]: https://github.com/SAP/ui5-cli/compare/v2.6.0...v2.6.1
+[v2.6.0]: https://github.com/SAP/ui5-cli/compare/v2.5.0...v2.6.0
+[v2.5.0]: https://github.com/SAP/ui5-cli/compare/v2.4.5...v2.5.0
+[v2.4.5]: https://github.com/SAP/ui5-cli/compare/v2.4.4...v2.4.5
+[v2.4.4]: https://github.com/SAP/ui5-cli/compare/v2.4.3...v2.4.4
+[v2.4.3]: https://github.com/SAP/ui5-cli/compare/v2.4.2...v2.4.3
+[v2.4.2]: https://github.com/SAP/ui5-cli/compare/v2.4.1...v2.4.2
+[v2.4.1]: https://github.com/SAP/ui5-cli/compare/v2.4.0...v2.4.1
+[v2.4.0]: https://github.com/SAP/ui5-cli/compare/v2.3.2...v2.4.0
+[v2.3.2]: https://github.com/SAP/ui5-cli/compare/v2.3.1...v2.3.2
+[v2.3.1]: https://github.com/SAP/ui5-cli/compare/v2.3.0...v2.3.1
+[v2.3.0]: https://github.com/SAP/ui5-cli/compare/v2.2.6...v2.3.0
+[v2.2.6]: https://github.com/SAP/ui5-cli/compare/v2.2.5...v2.2.6
+[v2.2.5]: https://github.com/SAP/ui5-cli/compare/v2.2.4...v2.2.5
+[v2.2.4]: https://github.com/SAP/ui5-cli/compare/v2.2.3...v2.2.4
+[v2.2.3]: https://github.com/SAP/ui5-cli/compare/v2.2.2...v2.2.3
+[v2.2.2]: https://github.com/SAP/ui5-cli/compare/v2.2.1...v2.2.2
+[v2.2.1]: https://github.com/SAP/ui5-cli/compare/v2.2.0...v2.2.1
+[v2.2.0]: https://github.com/SAP/ui5-cli/compare/v2.1.0...v2.2.0
+[v2.1.0]: https://github.com/SAP/ui5-cli/compare/v2.0.3...v2.1.0
+[v2.0.3]: https://github.com/SAP/ui5-cli/compare/v2.0.2...v2.0.3
+[v2.0.2]: https://github.com/SAP/ui5-cli/compare/v2.0.1...v2.0.2
+[v2.0.1]: https://github.com/SAP/ui5-cli/compare/v2.0.0...v2.0.1
+[v2.0.0]: https://github.com/SAP/ui5-cli/compare/v1.14.0...v2.0.0
+[v1.14.0]: https://github.com/SAP/ui5-cli/compare/v1.13.1...v1.14.0
+[v1.13.1]: https://github.com/SAP/ui5-cli/compare/v1.13.0...v1.13.1
+[v1.13.0]: https://github.com/SAP/ui5-cli/compare/v1.12.2...v1.13.0
+[v1.12.2]: https://github.com/SAP/ui5-cli/compare/v1.12.1...v1.12.2
+[v1.12.1]: https://github.com/SAP/ui5-cli/compare/v1.12.0...v1.12.1
+[v1.12.0]: https://github.com/SAP/ui5-cli/compare/v1.11.1...v1.12.0
+[v1.11.1]: https://github.com/SAP/ui5-cli/compare/v1.11.0...v1.11.1
+[v1.11.0]: https://github.com/SAP/ui5-cli/compare/v1.10.0...v1.11.0
+[v1.10.0]: https://github.com/SAP/ui5-cli/compare/v1.9.0...v1.10.0
+[v1.9.0]: https://github.com/SAP/ui5-cli/compare/v1.8.1...v1.9.0
+[v1.8.1]: https://github.com/SAP/ui5-cli/compare/v1.8.0...v1.8.1
+[v1.8.0]: https://github.com/SAP/ui5-cli/compare/v1.7.0...v1.8.0
+[v1.7.0]: https://github.com/SAP/ui5-cli/compare/v1.6.0...v1.7.0
+[v1.6.0]: https://github.com/SAP/ui5-cli/compare/v1.5.5...v1.6.0
+[v1.5.5]: https://github.com/SAP/ui5-cli/compare/v1.5.4...v1.5.5
+[v1.5.4]: https://github.com/SAP/ui5-cli/compare/v1.5.3...v1.5.4
+[v1.5.3]: https://github.com/SAP/ui5-cli/compare/v1.5.2...v1.5.3
+[v1.5.2]: https://github.com/SAP/ui5-cli/compare/v1.5.1...v1.5.2
+[v1.5.1]: https://github.com/SAP/ui5-cli/compare/v1.5.0...v1.5.1
+[v1.5.0]: https://github.com/SAP/ui5-cli/compare/v1.4.4...v1.5.0
+[v1.4.4]: https://github.com/SAP/ui5-cli/compare/v1.4.3...v1.4.4
+[v1.4.3]: https://github.com/SAP/ui5-cli/compare/v1.4.2...v1.4.3
+[v1.4.2]: https://github.com/SAP/ui5-cli/compare/v1.4.1...v1.4.2
+[v1.4.1]: https://github.com/SAP/ui5-cli/compare/v1.4.0...v1.4.1
+[v1.4.0]: https://github.com/SAP/ui5-cli/compare/v1.3.1...v1.4.0
+[v1.3.1]: https://github.com/SAP/ui5-cli/compare/v1.3.0...v1.3.1
+[v1.3.0]: https://github.com/SAP/ui5-cli/compare/v1.2.4...v1.3.0
+[v1.2.4]: https://github.com/SAP/ui5-cli/compare/v1.2.3...v1.2.4
+[v1.2.3]: https://github.com/SAP/ui5-cli/compare/v1.2.2...v1.2.3
+[v1.2.2]: https://github.com/SAP/ui5-cli/compare/v1.2.1...v1.2.2
+[v1.2.1]: https://github.com/SAP/ui5-cli/compare/v1.2.0...v1.2.1
+[v1.2.0]: https://github.com/SAP/ui5-cli/compare/v1.1.0...v1.2.0
+[v1.1.0]: https://github.com/SAP/ui5-cli/compare/v1.0.1...v1.1.0
+[v1.0.1]: https://github.com/SAP/ui5-cli/compare/v1.0.0...v1.0.1
+[v1.0.0]: https://github.com/SAP/ui5-cli/compare/v0.2.9...v1.0.0
+[v0.2.9]: https://github.com/SAP/ui5-cli/compare/v0.2.8...v0.2.9
+[v0.2.8]: https://github.com/SAP/ui5-cli/compare/v0.2.7...v0.2.8
+[v0.2.7]: https://github.com/SAP/ui5-cli/compare/v0.2.6...v0.2.7
+[v0.2.6]: https://github.com/SAP/ui5-cli/compare/v0.2.5...v0.2.6
+[v0.2.5]: https://github.com/SAP/ui5-cli/compare/v0.2.4...v0.2.5
+[v0.2.4]: https://github.com/SAP/ui5-cli/compare/v0.2.3...v0.2.4
+[v0.2.3]: https://github.com/SAP/ui5-cli/compare/v0.2.2...v0.2.3
+[v0.2.2]: https://github.com/SAP/ui5-cli/compare/v0.2.1...v0.2.2
+[v0.2.1]: https://github.com/SAP/ui5-cli/compare/v0.2.0...v0.2.1
+[v0.2.0]: https://github.com/SAP/ui5-cli/compare/v0.1.0...v0.2.0
+[v0.1.0]: https://github.com/SAP/ui5-cli/compare/v0.0.2...v0.1.0
+[v0.0.2]: https://github.com/SAP/ui5-cli/compare/v0.0.1...v0.0.2
diff --git a/packages/cli/.chglog/RELEASE.tpl.md b/packages/cli/.chglog/RELEASE.tpl.md
new file mode 100755
index 00000000000..efc482c385d
--- /dev/null
+++ b/packages/cli/.chglog/RELEASE.tpl.md
@@ -0,0 +1,33 @@
+{{ range .Versions }}
+{{ range .CommitGroups -}}
+### {{ .Title }}
+{{ range .Commits -}}
+- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} [`{{ .Hash.Short }}`]({{ $.Info.RepositoryURL }}/commit/{{ .Hash.Long }})
+{{ end }}
+{{ end -}}
+
+{{- if .RevertCommits -}}
+### Reverts
+{{ range .RevertCommits -}}
+- {{ .Revert.Header }}
+{{ end }}
+{{ end -}}
+
+{{- if .NoteGroups -}}
+{{ range .NoteGroups -}}
+### {{ .Title }}
+{{ range .Notes }}
+{{ .Body }}
+{{ end }}
+{{ end -}}
+{{ end -}}
+
+{{ if .Tag.Previous }}
+### All changes
+[`{{ .Tag.Previous.Name }}...{{ .Tag.Name }}`]
+{{ end }}
+
+{{ if .Tag.Previous -}}
+[`{{ .Tag.Previous.Name }}...{{ .Tag.Name }}`]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
+{{ end -}}
+{{ end -}}
diff --git a/packages/cli/.chglog/config.yml b/packages/cli/.chglog/config.yml
new file mode 100755
index 00000000000..67dd3c1e9ec
--- /dev/null
+++ b/packages/cli/.chglog/config.yml
@@ -0,0 +1,33 @@
+style: github
+template: CHANGELOG.tpl.md
+info:
+ title: CHANGELOG
+ repository_url: https://github.com/SAP/ui5-cli
+options:
+ commits:
+ filters:
+ Type:
+ - FEATURE
+ - FIX
+ - PERF
+ - DEPENDENCY
+ - BREAKING
+ commit_groups:
+ title_maps:
+ FEATURE: Features
+ FIX: Bug Fixes
+ PERF: Performance Improvements
+ DEPENDENCY: Dependency Updates
+ BREAKING: Breaking Changes
+ header:
+ pattern: "^\\[(\\w*)\\]\\s(?:([^\\:]*)\\:\\s)?(.*)$"
+ pattern_maps:
+ - Type
+ - Scope
+ - Subject
+ issues:
+ prefix:
+ - "#"
+ notes:
+ keywords:
+ - BREAKING CHANGE
diff --git a/packages/cli/.chglog/consolidate-changelogs.js b/packages/cli/.chglog/consolidate-changelogs.js
new file mode 100644
index 00000000000..ab024c1c769
--- /dev/null
+++ b/packages/cli/.chglog/consolidate-changelogs.js
@@ -0,0 +1,66 @@
+import readline from "node:readline";
+import fs from "node:fs";
+import {fileURLToPath} from "node:url";
+
+function handleDependencyBump(line) {
+ line = line.replace("[@ui5](https://github.com/ui5)", "@ui5");
+ const moduleMatch = line.match(/Bump (@ui5\/[^\s]+).*to ([^ ]+)/);
+ if (moduleMatch) {
+ const [, moduleName, moduleVersion] = moduleMatch;
+ const changelogPath = fileURLToPath(
+ new URL(`./CHANGELOG.md`, import.meta.resolve(`${moduleName}/package.json`)));
+ const changelog = fs.readFileSync(changelogPath, {
+ encoding: "utf8"
+ });
+ const sectionRegExp =
+ new RegExp(`^## \\[v${moduleVersion.replace(".", "\\.")}\\].+\\n((?:.|\\n)+?)(?=^ 1) {
+ versionChangelog = versionChangelog.replace(/^### /gm, "#### ");
+ versionChangelog = versionChangelog.replace(/^./gm, " $&");
+ const repoUrl = `https://github.com/SAP/${moduleName.replace("@ui5/", "ui5-")}/tree/v${moduleVersion}`;
+ line += `
+ - Changes contained in [${moduleName}@${moduleVersion}](${repoUrl}):
+
+${versionChangelog}`;
+ } else {
+ // In case of an empty changelog: Only add the required newline
+ line += "\n";
+ }
+ }
+ return line;
+}
+
+function readStdin() {
+ return new Promise((resolve, reject) => {
+ const rl = readline.createInterface({
+ input: process.stdin,
+ });
+
+ let buffer = "";
+ rl.on("line", (line) => {
+ try {
+ if (line.startsWith("- Bump")) {
+ buffer += `${handleDependencyBump(line)}`;
+ } else {
+ buffer += `${line}\n`;
+ }
+ } catch (err) {
+ reject(err);
+ }
+ });
+
+ rl.on("pause", () => {
+ resolve(buffer);
+ });
+ });
+}
+
+readStdin().then((result) => {
+ process.stdout.write(result); // Don't use console.log since one new line at the end is already enough
+});
diff --git a/packages/cli/.chglog/release-config.yml b/packages/cli/.chglog/release-config.yml
new file mode 100755
index 00000000000..154e6bd1078
--- /dev/null
+++ b/packages/cli/.chglog/release-config.yml
@@ -0,0 +1,33 @@
+style: github
+template: RELEASE.tpl.md
+info:
+ repository_url: https://github.com/SAP/ui5-cli
+options:
+ tag_filter_pattern: '^v[^0123]' # For release notes ignore versions below v4 to that we always compare the _last v4+_ tag with the current release
+ commits:
+ filters:
+ Type:
+ - FEATURE
+ - FIX
+ - PERF
+ - DEPENDENCY
+ - BREAKING
+ commit_groups:
+ title_maps:
+ FEATURE: Features
+ FIX: Bug Fixes
+ PERF: Performance Improvements
+ DEPENDENCY: Dependency Updates
+ BREAKING: Breaking Changes
+ header:
+ pattern: "^\\[(\\w*)\\]\\s(?:([^\\:]*)\\:\\s)?(.*)$"
+ pattern_maps:
+ - Type
+ - Scope
+ - Subject
+ issues:
+ prefix:
+ - "#"
+ notes:
+ keywords:
+ - BREAKING CHANGE
diff --git a/packages/cli/.dockerignore b/packages/cli/.dockerignore
new file mode 100644
index 00000000000..052409d713d
--- /dev/null
+++ b/packages/cli/.dockerignore
@@ -0,0 +1,62 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# CI (Azure Pipelines) xUnit test results
+test-results.xml
+
+# IDEs
+.vscode/
+*.~vsdx
+.idea/
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules
+jspm_packages
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# Misc
+yarn.lock
+.DS_Store
+
+# Don't include private SSH key for deployment via Travis CI
+deploy_key
+
+# Custom directories
+test/tmp/
+jsdocs/
diff --git a/packages/cli/.editorconfig b/packages/cli/.editorconfig
new file mode 100644
index 00000000000..b432804f7fc
--- /dev/null
+++ b/packages/cli/.editorconfig
@@ -0,0 +1,20 @@
+# see http://editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+indent_style = tab
+
+[*.{css,html,js,cjs,mjs,jsx,ts,tsx,less,txt,json,yml,md}]
+trim_trailing_whitespace = true
+end_of_line = lf
+indent_size = 4
+insert_final_newline = true
+
+[*.{yml,yaml}]
+indent_style = space
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/packages/cli/.gitattributes b/packages/cli/.gitattributes
new file mode 100644
index 00000000000..6313b56c578
--- /dev/null
+++ b/packages/cli/.gitattributes
@@ -0,0 +1 @@
+* text=auto eol=lf
diff --git a/packages/cli/.github/ISSUE_TEMPLATE.md b/packages/cli/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000000..6ddeb2221a8
--- /dev/null
+++ b/packages/cli/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,3 @@
+## 🚨 Issues Have Been Transferred to UI5 CLI Repository
+
+Please create new issues in the UI5 CLI repository: https://github.com/UI5/cli/issues/new/choose
diff --git a/packages/cli/.github/ISSUE_TEMPLATE/config.yml b/packages/cli/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000000..34df09809c9
--- /dev/null
+++ b/packages/cli/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Report UI5 CLI Issues or Request a Feature
+ url: https://github.com/UI5/cli/issues/new/choose
+ about: Please create new issues in the UI5 CLI repository
diff --git a/packages/cli/.github/PULL_REQUEST_TEMPLATE.md b/packages/cli/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000000..2f043b5c5cc
--- /dev/null
+++ b/packages/cli/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,9 @@
+**Thank you for your contribution!** 🙌
+
+To get it merged faster, kindly review the checklist below:
+
+## Pull Request Checklist
+- [ ] Reviewed the [Contributing Guidelines](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md#-contributing-code)
+ + Especially the [How to Contribute](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md#how-to-contribute) section
+- [ ] [No merge commits](https://github.com/UI5/cli/blob/main/docs/Guidelines.md#no-merge-commits)
+- [ ] [Correct commit message style](https://github.com/UI5/cli/blob/main/docs/Guidelines.md#commit-message-style)
diff --git a/packages/cli/.github/dependabot.yml b/packages/cli/.github/dependabot.yml
new file mode 100644
index 00000000000..ebf6ca750f8
--- /dev/null
+++ b/packages/cli/.github/dependabot.yml
@@ -0,0 +1,19 @@
+version: 2
+updates:
+- package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+- package-ecosystem: npm
+ directory: "/"
+ schedule:
+ interval: weekly
+ day: sunday
+ time: "10:00"
+ timezone: Etc/UCT
+ reviewers:
+ - "SAP/ui5-foundation"
+ versioning-strategy: increase
+ commit-message:
+ prefix: "[DEPENDENCY] "
+ prefix-development: "[INTERNAL] "
diff --git a/packages/cli/.github/in-solidarity.yml b/packages/cli/.github/in-solidarity.yml
new file mode 100644
index 00000000000..4ce829a6be3
--- /dev/null
+++ b/packages/cli/.github/in-solidarity.yml
@@ -0,0 +1 @@
+_extends: ietf/terminology
diff --git a/packages/cli/.github/workflows/dependabot-auto-merge.yml b/packages/cli/.github/workflows/dependabot-auto-merge.yml
new file mode 100644
index 00000000000..43d92c94fd6
--- /dev/null
+++ b/packages/cli/.github/workflows/dependabot-auto-merge.yml
@@ -0,0 +1,28 @@
+name: Dependabot auto-merge
+on:
+ pull_request:
+ branches:
+ - v4
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ dependabot:
+ runs-on: ubuntu-latest
+ if: ${{ github.actor == 'dependabot[bot]' && github.event.pull_request.auto_merge == null }}
+ steps:
+ - name: Dependabot metadata
+ id: metadata
+ uses: dependabot/fetch-metadata@v2
+ with:
+ github-token: "${{ secrets.GITHUB_TOKEN }}"
+ - name: Approve and auto-merge PRs for minor/patch updates of github-actions
+ if: |
+ steps.metadata.outputs.package-ecosystem == 'github_actions' &&
+ contains(fromJSON('["version-update:semver-minor", "version-update:semver-patch"]'), steps.metadata.outputs.update-type)
+ run: gh pr review --approve "$PR_URL" && gh pr merge --auto --rebase "$PR_URL"
+ env:
+ PR_URL: ${{github.event.pull_request.html_url}}
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
diff --git a/packages/cli/.github/workflows/github-ci.yml b/packages/cli/.github/workflows/github-ci.yml
new file mode 100644
index 00000000000..733b72d7f9d
--- /dev/null
+++ b/packages/cli/.github/workflows/github-ci.yml
@@ -0,0 +1,40 @@
+name: GitHub CI
+
+on:
+ push:
+ branches:
+ - v4
+ pull_request:
+ branches:
+ - v4
+
+# No permissions are required for this workflow
+permissions: {}
+
+jobs:
+ test:
+ name: General checks, tests and coverage reporting
+ runs-on: ubuntu-24.04
+ steps:
+
+ - uses: actions/checkout@v5
+
+ - name: Use Node.js LTS 20.11.0
+ uses: actions/setup-node@v4.4.0
+ with:
+ node-version: 20.11.0
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Perform checks and tests
+ run: npm test
+
+ - name: Send report to Coveralls
+ uses: coverallsapp/github-action@v2.3.6
+
+ - name: Build e2e test image
+ run: ./test/e2e/build-image.sh
+
+ - name: Run e2e test image
+ run: ./test/e2e/run-image.sh
diff --git a/packages/cli/.github/workflows/reuse-compliance.yml b/packages/cli/.github/workflows/reuse-compliance.yml
new file mode 100644
index 00000000000..ee696a44f1b
--- /dev/null
+++ b/packages/cli/.github/workflows/reuse-compliance.yml
@@ -0,0 +1,21 @@
+name: REUSE
+
+on:
+ push:
+ branches:
+ - v4
+ pull_request:
+ branches:
+ - v4
+
+# No permissions are required for this workflow
+permissions: {}
+
+jobs:
+ compliance-check:
+ name: Compliance Check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
+ - name: Execute REUSE Compliance Check
+ uses: fsfe/reuse-action@v5
diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore
new file mode 100644
index 00000000000..052409d713d
--- /dev/null
+++ b/packages/cli/.gitignore
@@ -0,0 +1,62 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# CI (Azure Pipelines) xUnit test results
+test-results.xml
+
+# IDEs
+.vscode/
+*.~vsdx
+.idea/
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules
+jspm_packages
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# Misc
+yarn.lock
+.DS_Store
+
+# Don't include private SSH key for deployment via Travis CI
+deploy_key
+
+# Custom directories
+test/tmp/
+jsdocs/
diff --git a/packages/cli/.licensee.json b/packages/cli/.licensee.json
new file mode 100644
index 00000000000..e14c1295196
--- /dev/null
+++ b/packages/cli/.licensee.json
@@ -0,0 +1,15 @@
+{
+ "licenses": {
+ "spdx": [
+ "CC-BY-3.0",
+ "CC-BY-4.0",
+ "BSD"
+ ],
+ "blueOak": "bronze"
+ },
+ "packages": {
+ "callsite": "1.0.0",
+ "yesno": "0.4.0"
+ },
+ "corrections": true
+}
diff --git a/packages/cli/.npmrc b/packages/cli/.npmrc
new file mode 100644
index 00000000000..93ec4f76ba6
--- /dev/null
+++ b/packages/cli/.npmrc
@@ -0,0 +1,3 @@
+# Enforce public npm registry
+registry=https://registry.npmjs.org/
+lockfile-version=3
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
new file mode 100644
index 00000000000..b04f256072d
--- /dev/null
+++ b/packages/cli/CHANGELOG.md
@@ -0,0 +1,1560 @@
+# Changelog
+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-cli/compare/v4.0.26...HEAD).
+
+
+## [v4.0.26] - 2025-09-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 4.0.5 to 4.0.6 [`797e069`](https://github.com/SAP/ui5-cli/commit/797e069bdfaa76e26396cb6b1a74c2ccb49b76f1)
+
+
+
+## [v4.0.25] - 2025-09-11
+### Bug Fixes
+- Rename project to UI5 CLI [`4ab403c`](https://github.com/SAP/ui5-cli/commit/4ab403cc3791e1e9cb38c811f1b4fd96bc4cc8e5)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.6 to 4.0.7 [`76c5d49`](https://github.com/SAP/ui5-cli/commit/76c5d49a74dad86364afdab0a31f18cf8430af63)
+- Bump [@ui5](https://github.com/ui5)/project from 4.0.4 to 4.0.5 [`e31e274`](https://github.com/SAP/ui5-cli/commit/e31e2745a22d9d6aa4d90f1b40cdb11abf1a15da)
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.10 to 4.0.11 [`741d91c`](https://github.com/SAP/ui5-cli/commit/741d91cd47289a4e73a6819892bb1ecddf32717c)
+
+
+
+## [v4.0.24] - 2025-09-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.9 to 4.0.10 [`c4169ff`](https://github.com/SAP/ui5-cli/commit/c4169ff5eda412e133dc7996207d07fe5626447e)
+
+
+
+## [v4.0.23] - 2025-08-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.8 to 4.0.9 [`6ee6205`](https://github.com/SAP/ui5-cli/commit/6ee6205a4281603cbec27798b44f501393fd6862)
+
+
+
+## [v4.0.22] - 2025-07-18
+
+
+## [v4.0.21] - 2025-07-16
+### Bug Fixes
+- **serve:** Respect `--config` option with `--dependency-definition` [`e043cd7`](https://github.com/SAP/ui5-cli/commit/e043cd7d3783b3289e903498be38f91504a461ab)
+
+
+
+## [v4.0.20] - 2025-07-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.7 to 4.0.8 [`9d1167d`](https://github.com/SAP/ui5-cli/commit/9d1167d09b15716a71d1c002e76c3c445cb807e3)
+
+
+
+## [v4.0.19] - 2025-06-17
+
+
+## [v4.0.18] - 2025-06-06
+
+
+## [v4.0.17] - 2025-06-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.5 to 4.0.6 [`f29d8ae`](https://github.com/SAP/ui5-cli/commit/f29d8ae4965cdaa0a845df8ed6b65ed0b1a09d29)
+
+
+
+## [v4.0.16] - 2025-05-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.6 to 4.0.7 [`a07bfb4`](https://github.com/SAP/ui5-cli/commit/a07bfb488bb5a91424bee6b4d677b2a7eea51cd6)
+
+
+
+## [v4.0.15] - 2025-04-29
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.5 to 4.0.6 [`e8371de`](https://github.com/SAP/ui5-cli/commit/e8371de5cd2c7616718a1e8700551552b2bd418e)
+
+
+
+## [v4.0.14] - 2025-03-20
+### Bug Fixes
+- Invocation of local CLI on Windows [`3bd6e83`](https://github.com/SAP/ui5-cli/commit/3bd6e83b09489d9d13499c6381808d79e8f21f4d)
+
+
+
+## [v4.0.13] - 2025-01-22
+
+
+## [v4.0.12] - 2024-12-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.4 to 4.0.5 [`9ee3c97`](https://github.com/SAP/ui5-cli/commit/9ee3c97312afcfa073ba0ab972d46212336197eb)
+
+
+
+## [v4.0.11] - 2024-11-29
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 4.0.3 to 4.0.4 [`334e2e1`](https://github.com/SAP/ui5-cli/commit/334e2e1fee0e7ee6f9b8f0c536cd2f2efd4c3f15)
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.3 to 4.0.4 [`ada646c`](https://github.com/SAP/ui5-cli/commit/ada646cb6668cc9ddc03ac99aef7b992d5f2bbec)
+
+
+
+## [v4.0.10] - 2024-11-13
+
+
+## [v4.0.9] - 2024-10-15
+
+
+## [v4.0.8] - 2024-09-12
+
+
+## [v4.0.7] - 2024-09-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.4 to 4.0.5 [`eae76c2`](https://github.com/SAP/ui5-cli/commit/eae76c2abb985900571f228f7a6ec8f58b105a82)
+
+
+
+## [v4.0.6] - 2024-08-27
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.3 to 4.0.4 [`1665718`](https://github.com/SAP/ui5-cli/commit/16657182adf55d69a724e2f1c3fcf71997b86aee)
+- Bump [@ui5](https://github.com/ui5)/project from 4.0.2 to 4.0.3 [`f4ef755`](https://github.com/SAP/ui5-cli/commit/f4ef755639cac9e9d7bb1e6d157c4bd98967557f)
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.2 to 4.0.3 [`1e65819`](https://github.com/SAP/ui5-cli/commit/1e65819f446e280b257baceb08425d621a01d486)
+- Bump [@ui5](https://github.com/ui5)/fs from 4.0.0 to 4.0.1 [`befd45b`](https://github.com/SAP/ui5-cli/commit/befd45b096fba4f3d08a161e6092d777072bba4b)
+
+
+
+## [v4.0.5] - 2024-08-20
+### Bug Fixes
+- Print error cause stack trace [`323845c`](https://github.com/SAP/ui5-cli/commit/323845cefe48c22c3224864e55d91f82762e6246)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.1 to 4.0.2 [`dabb3f5`](https://github.com/SAP/ui5-cli/commit/dabb3f57eef2b3506061e36bae8c10b8a296ca96)
+
+
+
+## [v4.0.4] - 2024-08-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.2 to 4.0.3 [`b94ede8`](https://github.com/SAP/ui5-cli/commit/b94ede8bea9c126d743b56b33221d9f570746449)
+
+
+
+## [v4.0.3] - 2024-08-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.1 to 4.0.2 [`df15ffa`](https://github.com/SAP/ui5-cli/commit/df15ffaac789978fae18b698de73b49214173b0f)
+- Bump [@ui5](https://github.com/ui5)/project from 4.0.1 to 4.0.2 [`db925ab`](https://github.com/SAP/ui5-cli/commit/db925ab7f3d5c40637cfa491ffde5fd2f276cab7)
+
+
+
+## [v4.0.2] - 2024-07-31
+### Bug Fixes
+- Node.js ExperimentalWarning shown on console [`011b34e`](https://github.com/SAP/ui5-cli/commit/011b34e22081fe415ed46caa2debd9a3091f6d54)
+
+
+
+## [v4.0.1] - 2024-07-31
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 4.0.0 to 4.0.1 [`6c33995`](https://github.com/SAP/ui5-cli/commit/6c339957e0e74d00a90aa067ca553ecbc0cd0747)
+- Bump [@ui5](https://github.com/ui5)/project from 4.0.0 to 4.0.1 [`eaab649`](https://github.com/SAP/ui5-cli/commit/eaab64930f101b9ae73fa3920b94fbf98bace511)
+- Bump [@ui5](https://github.com/ui5)/builder from 4.0.0 to 4.0.1 [`4e5b9be`](https://github.com/SAP/ui5-cli/commit/4e5b9be808105c1e1ea53723b1593f2b7cf8e427)
+
+
+
+## [v4.0.0] - 2024-07-24
+### Breaking Changes
+- Drop node v21 support ([#720](https://github.com/SAP/ui5-cli/issues/720)) [`891306f`](https://github.com/SAP/ui5-cli/commit/891306f736eaf6cfebd1bf7a04511fcbac65ef02)
+- Replace console.log with process.stderr ([#686](https://github.com/SAP/ui5-cli/issues/686)) [`48d1975`](https://github.com/SAP/ui5-cli/commit/48d1975c09686e9bd28312cf59a73ede3bc3d47b)
+- Rename ui5HomeDir to ui5DataDir in APIs ([#687](https://github.com/SAP/ui5-cli/issues/687)) [`772ac29`](https://github.com/SAP/ui5-cli/commit/772ac29515a55637cc55924ef0462ca76058a073)
+- Require Node.js 20.11.x/>=21.2.0 and npm >=10 [`59314fa`](https://github.com/SAP/ui5-cli/commit/59314fabae8c66dbefcc21e2557a11373dc8a8c7)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.5.1 to 4.0.0 [`0ce3196`](https://github.com/SAP/ui5-cli/commit/0ce3196c0c8c8780b6d3e940caf9fd99a9e89f6b)
+- Bump [@ui5](https://github.com/ui5)/project from 3.9.2 to 4.0.0 [`0d7302b`](https://github.com/SAP/ui5-cli/commit/0d7302b4d5e83c2083ef850f81f4007f74809d4b)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.5 to 4.0.0 [`ce51fc2`](https://github.com/SAP/ui5-cli/commit/ce51fc2442ca1ae80a5468b7288a8d51f176bc01)
+- Bump [@ui5](https://github.com/ui5)/logger from 3.0.0 to 4.0.1 [`04b201c`](https://github.com/SAP/ui5-cli/commit/04b201c14439fb33f1de4c50a7cf4d00cc80ec49)
+- Bump [@ui5](https://github.com/ui5)/server from 3.2.1 to 4.0.0 [`095f31d`](https://github.com/SAP/ui5-cli/commit/095f31dbeb90bbaf310a02b2b25ad1a088d1347f)
+- Bump update-notifier from 6.0.2 to 7.0.0 [`cd33dbd`](https://github.com/SAP/ui5-cli/commit/cd33dbd95f9364f882a91515187e48ff5b3f3c94)
+- Bump open from 9.1.0 to 10.0.3 [`486f8ef`](https://github.com/SAP/ui5-cli/commit/486f8efb98f82626fb32b7af04af94375ac41618)
+
+### BREAKING CHANGE
+
+System messages will now be written to stderr instead of stdout.
+
+JIRA: CPOUI5FOUNDATION-802
+Related to: https://github.com/SAP/ui5-tooling/issues/701
+Sibling of: https://github.com/SAP/ui5-server/pull/643,
+https://github.com/SAP/ui5-tooling/pull/930
+
+
+
+Support for older Node.js and npm releases has been dropped.
+Only Node.js 20.11.x and >=21.2.0 as well as npm v10 or higher are supported.
+
+
+## [v3.11.1] - 2024-07-22
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.5.0 to 3.5.1 [`00c050f`](https://github.com/SAP/ui5-cli/commit/00c050f929aa6204a5d57ead9845dd24fe5f8704)
+
+
+## [v3.11.0] - 2024-06-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.9.1 to 3.9.2 [`e74c280`](https://github.com/SAP/ui5-cli/commit/e74c28018eafb9b15da56dcb45de58fbedec5ced)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.4.1 to 3.5.0 [`d8bf229`](https://github.com/SAP/ui5-cli/commit/d8bf2295933998e64c4241942b2d93cb663eb068)
+
+
+## [v3.10.3] - 2024-05-22
+
+
+## [v3.10.2] - 2024-05-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 3.2.0 to 3.2.1 [`f8bc6b3`](https://github.com/SAP/ui5-cli/commit/f8bc6b343c0d8cdbfcc37cbca36699b0cc9e9e36)
+
+
+
+## [v3.10.1] - 2024-05-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.4.0 to 3.4.1 [`7c072df`](https://github.com/SAP/ui5-cli/commit/7c072df00fa205d083c68934dac42a9abec94dcc)
+
+
+
+## [v3.10.0] - 2024-04-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.5 to 3.2.0 [`3aae04d`](https://github.com/SAP/ui5-cli/commit/3aae04d9e60c162d42d6e5c75906cdb563bbe761)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.3.1 to 3.4.0 [`023693e`](https://github.com/SAP/ui5-cli/commit/023693e4790a6c7f2ba12492fd5868f27234620e)
+
+
+
+## [v3.9.2] - 2024-03-27
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.3.0 to 3.3.1 [`c1d3b76`](https://github.com/SAP/ui5-cli/commit/c1d3b76dc0670f0a65334d269b804c1a49a82dba)
+
+
+
+## [v3.9.1] - 2024-02-13
+
+
+## [v3.9.0] - 2024-01-18
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.2.0 to 3.3.0 [`9b3f5fd`](https://github.com/SAP/ui5-cli/commit/9b3f5fdfb636a45bd78472ade475b5ac9343dd92)
+
+
+
+## [v3.8.0] - 2023-12-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.8.0 to 3.9.0 [`09f1ea9`](https://github.com/SAP/ui5-cli/commit/09f1ea9310d95636a87a6017a5d264594234b798)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.4 to 3.1.5 [`191b80c`](https://github.com/SAP/ui5-cli/commit/191b80c123840a7556385f08a964bf0f514813a7)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.1.1 to 3.2.0 [`d63a77e`](https://github.com/SAP/ui5-cli/commit/d63a77ec25c98f1f2c2ba3dbbfc69aea95c5ea6a)
+
+### Features
+- Add option to redefine output directory structure ([#665](https://github.com/SAP/ui5-cli/issues/665)) [`388dc79`](https://github.com/SAP/ui5-cli/commit/388dc793fe2344f1f59717f3a9d1ea230b0337dd)
+
+
+
+## [v3.7.3] - 2023-12-01
+
+
+## [v3.7.2] - 2023-11-21
+### Bug Fixes
+- **ui5 init:** Improve error message ([#661](https://github.com/SAP/ui5-cli/issues/661)) [`07e68b0`](https://github.com/SAP/ui5-cli/commit/07e68b00ff5cd2e80c0b1b52fa644e27752ccecb)
+- **ui5.yaml:** Use double quotes for string values ([#660](https://github.com/SAP/ui5-cli/issues/660)) [`c30e371`](https://github.com/SAP/ui5-cli/commit/c30e371be147d859539afbe9a44cc03202a8c870)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.3 to 3.8.0 [`2566170`](https://github.com/SAP/ui5-cli/commit/25661708c2b84f9c21d326c2d4ccb84464d7d2b5)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.3 to 3.1.4 [`2c90ff5`](https://github.com/SAP/ui5-cli/commit/2c90ff542dd5862603ebd0cc927ca71cd243cb8c)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.1.0 to 3.1.1 [`7b97356`](https://github.com/SAP/ui5-cli/commit/7b973566aa647ba1e2b271fa1c77b1bd7025c9ca)
+
+
+
+## [v3.7.1] - 2023-10-20
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.2 to 3.7.3 [`c59d1fb`](https://github.com/SAP/ui5-cli/commit/c59d1fb7577a17590c55b111fb1bcbd30c3ba425)
+
+
+
+## [v3.7.0] - 2023-10-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.1 to 3.7.2 [`0cba692`](https://github.com/SAP/ui5-cli/commit/0cba6927b847d205241bb86628468a22ccd0b999)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.9 to 3.1.0 [`0230f09`](https://github.com/SAP/ui5-cli/commit/0230f0965f146af99095a738899fd048d98218c9)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.4 to 3.0.5 [`e0da997`](https://github.com/SAP/ui5-cli/commit/e0da997b5e4e09f7509f2bf095b85bcf65b491ff)
+
+
+
+## [v3.6.1] - 2023-10-02
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.7.0 to 3.7.1 [`3f2d021`](https://github.com/SAP/ui5-cli/commit/3f2d021f01c1506281f264caed8643cac5af66a7)
+
+
+
+## [v3.6.0] - 2023-09-06
+### Bug Fixes
+- Update help description for "use" and "--framework-version" [`b042542`](https://github.com/SAP/ui5-cli/commit/b0425423ecd56ff8a24feaf3c7526ffeafe6d11f)
+- Ensure usage of provided UI5 data dir [`d7aaf35`](https://github.com/SAP/ui5-cli/commit/d7aaf35b69f2705860d229415db46cf751aea6b2)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.6.0 to 3.7.0 [`ecf52b4`](https://github.com/SAP/ui5-cli/commit/ecf52b4ab5c4d7c2b3c497e59fb220a350906a94)
+
+
+
+## [v3.5.0] - 2023-08-22
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.5.1 to 3.6.0 [`e5627d8`](https://github.com/SAP/ui5-cli/commit/e5627d81c9e66668bb99d128a304d403df9fd224)
+
+
+
+## [v3.4.1] - 2023-10-24
+### Bug Fixes
+- **ui5 config:** Allow usage of all Configuration options ([#645](https://github.com/SAP/ui5-cli/issues/645)) [`78e032e`](https://github.com/SAP/ui5-cli/commit/78e032ebd7d71ee59e6f6fd4f21dc0564e108d44)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.5.0 to 3.5.1 [`4ca30c3`](https://github.com/SAP/ui5-cli/commit/4ca30c3dc4066919f68af47307b4dc8b0bd898f7)
+
+
+
+## [v3.4.0] - 2023-08-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.4.2 to 3.5.0 [`c77a9e1`](https://github.com/SAP/ui5-cli/commit/c77a9e1bc2bd6f2e02c3c629e4c3f348a83e835c)
+
+
+
+## [v3.3.4] - 2023-07-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.8 to 3.0.9 [`efa562e`](https://github.com/SAP/ui5-cli/commit/efa562e0a893466c6b6d362056d17d87b558a94e)
+
+
+
+## [v3.3.3] - 2023-07-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.7 to 3.0.8 [`deba9bc`](https://github.com/SAP/ui5-cli/commit/deba9bcb93354393662035524a28c8d161b9c3f4)
+
+
+
+## [v3.3.2] - 2023-07-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.4.1 to 3.4.2 [`b55c982`](https://github.com/SAP/ui5-cli/commit/b55c98259c43878a36001e47a1e6a3386f706688)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.6 to 3.0.7 [`8d49876`](https://github.com/SAP/ui5-cli/commit/8d49876b4de7e53b93160a1e913a12f8ba935744)
+
+
+
+## [v3.3.1] - 2023-07-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.4.0 to 3.4.1 [`ebf23f4`](https://github.com/SAP/ui5-cli/commit/ebf23f4ed7ed3833579ee462647e626d16e73192)
+
+
+
+## [v3.3.0] - 2023-06-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.3.2 to 3.4.0 [`66d9caa`](https://github.com/SAP/ui5-cli/commit/66d9caa4a3ef50edf246ddf5e308a0b035f9c2a1)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.5 to 3.0.6 [`e504a14`](https://github.com/SAP/ui5-cli/commit/e504a1453feec43d74da9a03f58c47cdfdcfde5f)
+
+
+
+## [v3.2.0] - 2023-06-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.3.1 to 3.3.2 [`a508e96`](https://github.com/SAP/ui5-cli/commit/a508e966fb15de82c64754171fbd2202af3128e3)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.2 to 3.1.3 [`888fc0c`](https://github.com/SAP/ui5-cli/commit/888fc0cf918994cab1e3c84beac757e609a61566)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.4 to 3.0.5 [`1155cfc`](https://github.com/SAP/ui5-cli/commit/1155cfccb57f7d588063999719d1a0814fd7e939)
+
+### Features
+- **SNAPSHOT Consumption:** Add cache-mode parameter ([#633](https://github.com/SAP/ui5-cli/issues/633)) [`61d0865`](https://github.com/SAP/ui5-cli/commit/61d0865416eaee9bfc08195f636c60ad4f64e13f)
+- **ui5 tree:** Add 'level' and 'flat' parameters ([#635](https://github.com/SAP/ui5-cli/issues/635)) [`284d9ea`](https://github.com/SAP/ui5-cli/commit/284d9ea9f75967257859b7763e7b9a09a3b219cf)
+
+
+
+## [v3.1.3] - 2023-05-23
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.3.0 to 3.3.1 [`dbe7657`](https://github.com/SAP/ui5-cli/commit/dbe765789c2998e71dbc2acfe18029400c144159)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.3 to 3.0.4 [`44a7b21`](https://github.com/SAP/ui5-cli/commit/44a7b21618fe2892d6f99d5e97779a43cda24b8d)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.3 to 3.0.4 [`9ed9ce2`](https://github.com/SAP/ui5-cli/commit/9ed9ce206ac22dbe396d10a9ae5f8ff1345c28be)
+
+
+
+## [v3.1.2] - 2023-05-05
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.2.2 to 3.3.0 [`22c1c14`](https://github.com/SAP/ui5-cli/commit/22c1c1407253703e201df57555d94192ef7895d6)
+
+
+
+## [v3.1.1] - 2023-04-27
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.2.1 to 3.2.2 [`defb631`](https://github.com/SAP/ui5-cli/commit/defb6313fc651826876dd9713ee67fba72ced51c)
+
+
+
+## [v3.1.0] - 2023-04-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.2.0 to 3.2.1 [`922fb09`](https://github.com/SAP/ui5-cli/commit/922fb09c9cb6b8f317b8bba55a9a13f152532c73)
+- Bump [@ui5](https://github.com/ui5)/project from 3.1.1 to 3.2.0 [`4619e2f`](https://github.com/SAP/ui5-cli/commit/4619e2fc555987613920a4a30808534cbd70ab79)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.2 to 3.0.3 [`b5fbf4a`](https://github.com/SAP/ui5-cli/commit/b5fbf4adb094ab534d893d0f1e1f45226c52149b)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.2 to 3.0.3 [`c6fd1f8`](https://github.com/SAP/ui5-cli/commit/c6fd1f8c6c4c0d1419cb5820d6d37e173f528d1d)
+
+### Features
+- Add config command ([#618](https://github.com/SAP/ui5-cli/issues/618)) [`9910e30`](https://github.com/SAP/ui5-cli/commit/9910e304b80ca262587e99ab9a6118a4db15c584)
+
+
+
+## [v3.0.7] - 2023-04-12
+### Bug Fixes
+- Exit with code 1 when using unsupported Node.js version [`b232f83`](https://github.com/SAP/ui5-cli/commit/b232f8369a64bac2a1a599fe22d3d1ef03ff6eb0)
+- **init:** Use specVersion 3.0 [`45d0422`](https://github.com/SAP/ui5-cli/commit/45d04228052d2170c3b3c80f096c35d4c1fe0906)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.1.0 to 3.1.1 [`9f995f9`](https://github.com/SAP/ui5-cli/commit/9f995f980c3bef402771bfa3f321422949540e82)
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.1 to 3.1.2 [`145a88c`](https://github.com/SAP/ui5-cli/commit/145a88c90e0fda450d7fa6c44b724220736adede)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.1 to 3.0.2 [`caaa457`](https://github.com/SAP/ui5-cli/commit/caaa457f58ba45a79de4fa9ca3c7f594c9eb7f1e)
+- Bump open from 8.4.2 to 9.1.0 [`978c0b4`](https://github.com/SAP/ui5-cli/commit/978c0b432c4c6d1b21ef59b3e10ac0920ce3c934)
+
+
+
+## [v3.0.6] - 2023-03-31
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.4 to 3.1.0 [`676cabf`](https://github.com/SAP/ui5-cli/commit/676cabfec7416bcb023efbedef9821ee860094c6)
+
+
+
+## [v3.0.5] - 2023-03-16
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 3.1.0 to 3.1.1 [`c7f9be5`](https://github.com/SAP/ui5-cli/commit/c7f9be51aa42b351c81d3baca1d853d89b906b8c)
+
+
+
+## [v3.0.4] - 2023-03-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.3 to 3.0.4 [`cfbb720`](https://github.com/SAP/ui5-cli/commit/cfbb720bf3b5143a3c42f8ca9a2080bdba0aee89)
+
+
+
+## [v3.0.3] - 2023-03-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.2 to 3.0.3 [`1bef5f8`](https://github.com/SAP/ui5-cli/commit/1bef5f8bac9c2b8e929e1e543a8cbfed14ba079e)
+- Bump [@ui5](https://github.com/ui5)/server from 3.0.1 to 3.1.0 [`11427f4`](https://github.com/SAP/ui5-cli/commit/11427f4ee0cdf2d0c2db6bd7342cf98b246bf06c)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.1 to 3.0.2 [`c978d84`](https://github.com/SAP/ui5-cli/commit/c978d84da354d3284cbe9b2212b55aeefcb469e3)
+
+
+
+## [v3.0.2] - 2023-02-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.1 to 3.0.2 [`56ae640`](https://github.com/SAP/ui5-cli/commit/56ae64000ad23ca17652d5ab2b55366b5495d484)
+
+
+
+## [v3.0.1] - 2023-02-16
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 3.0.0 to 3.0.1 [`1dff14d`](https://github.com/SAP/ui5-cli/commit/1dff14d9a3994c5469a5d9e12bec237361c7d35b)
+- Bump [@ui5](https://github.com/ui5)/server from 3.0.0 to 3.0.1 [`d87daa9`](https://github.com/SAP/ui5-cli/commit/d87daa9990fb8039e10fea746925878d636b0d4a)
+- Bump [@ui5](https://github.com/ui5)/builder from 3.0.0 to 3.0.1 [`c578c4e`](https://github.com/SAP/ui5-cli/commit/c578c4e1072cc547c61d0fce860ecabcee209210)
+- Bump [@ui5](https://github.com/ui5)/fs from 3.0.0 to 3.0.1 [`80ed971`](https://github.com/SAP/ui5-cli/commit/80ed971e2f0b2ff973a20b1ebc19467bd12b4c35)
+
+
+
+## [v3.0.0] - 2023-02-09
+## Overview
+UI5 Tooling v3 provides general support for ES2022 ECMAScript language features. See [ECMAScript Support](https://sap.github.io/ui5-tooling/v3/pages/ESSupport/) for details.
+
+### Breaking Changes
+- **`@ui5/cli`:**
+ - Adapt to Project Graph APIs ([#413](https://github.com/SAP/ui5-cli/issues/413)) [`945b82b`](https://github.com/SAP/ui5-cli/commit/945b82bc775dc0a711529057908e9f36d8fadb62)
+- **`@ui5/project`:**
+ - Implement Project Graph, build execution [`161f462`](https://github.com/SAP/ui5-project/commit/161f462cf6a9955337fff512007125128c6c39dd)
+- **`@ui5/builder`:**
+ - **generateJsDoc:** Remove internal 'buildContext' parameter [`4ec80c8`](https://github.com/SAP/ui5-builder/commit/4ec80c874e177b658b1cd819431b6cb0660ded87)
+ - Removal of manifestBundler and generateManifestBundle ([#838](https://github.com/SAP/ui5-builder/issues/838)) [`07a5be2`](https://github.com/SAP/ui5-builder/commit/07a5be2b6d9aa23cf78ddd17951c832d6dec7bef)
+ - **JSDoc:** Fail build when jsdoc command failed ([#845](https://github.com/SAP/ui5-builder/issues/845)) [`c2916b4`](https://github.com/SAP/ui5-builder/commit/c2916b4f1d49b5500e4b51143d4e6065ac200eef)
+ - Remove build execution ([#740](https://github.com/SAP/ui5-builder/issues/740)) [`af2e956`](https://github.com/SAP/ui5-builder/commit/af2e956f6cba1275669160328e32df3fffa782d0)
+ - Enable modern preload bundles without dependencies ([#739](https://github.com/SAP/ui5-builder/issues/739)) [`97cfa6c`](https://github.com/SAP/ui5-builder/commit/97cfa6cd3eadff57bcc18816534c7751551ebdb8)
+ - **generateResourcesJson:** Make 'dependencies' parameter mandatory [`268dd16`](https://github.com/SAP/ui5-builder/commit/268dd16091c515ec0c922ea23af437d9aa8bf3ea)
+ - **moduleBundler:** Always default to `optimize: true` ([#685](https://github.com/SAP/ui5-builder/issues/685)) [`de5837c`](https://github.com/SAP/ui5-builder/commit/de5837c43449ea61deae3b2f02f9973f3fa37992)
+- **`@ui5/server`:**
+ - Remove "/proxy" endpoint ([#550](https://github.com/SAP/ui5-server/issues/550)) [`4bdf839`](https://github.com/SAP/ui5-server/commit/4bdf839e96f67ddbc4cb2a18216921d54df4006e)
+ - Require Project Graph ([#479](https://github.com/SAP/ui5-server/issues/479)) [`d62f85a`](https://github.com/SAP/ui5-server/commit/d62f85a193115a587dbf58225e8130318a475023)
+- **`@ui5/fs`:**
+ - Throw an error on write of a resource when path does not starts with virBasePath of the respective adapter ([#453](https://github.com/SAP/ui5-fs/issues/453)) [`d76575f`](https://github.com/SAP/ui5-fs/commit/d76575f8f05a0b6695285200ba595e532620daed)
+ - Clone resources when writing in and reading from the Memory ([#448](https://github.com/SAP/ui5-fs/issues/448)) [`3454bc1`](https://github.com/SAP/ui5-fs/commit/3454bc15be8a6ecd455b49607cb289e69b41d0f0)
+ - **AbstractAdapter:** Virtual base path must end with slash [`6d1f411`](https://github.com/SAP/ui5-fs/commit/6d1f4117a2b8bb1226540fafeec8341e4966177d)
+ - **resourceFactory:** Remove #createCollectionsForTree [`a4d15f6`](https://github.com/SAP/ui5-fs/commit/a4d15f61ae0416051658280bfd2f8635c7ddf44e)
+- **`@ui5/logger`:**
+ - Deprecate advanced APIs in preparation of refactoring [`3aea5e7`](https://github.com/SAP/ui5-logger/commit/3aea5e766f9bda156e8c7e62a2e8c65f613ef7e9)
+
+### Features
+- `@ui5/cli`:
+ - Add build flag "--experimental-css-variables" ([#501](https://github.com/SAP/ui5-cli/issues/501)) [`0b099db`](https://github.com/SAP/ui5-cli/commit/0b099db193ee94aa0bde8373e883fbc54098cd89)
+- `@ui5/project`:
+ - npm/Installer: Do not wrap promise provided by rimraf v4 ([#550](https://github.com/SAP/ui5-project/issues/550)) [`2d1ccda`](https://github.com/SAP/ui5-project/commit/2d1ccda54edd29dabadcb7bad9136bff09da8eac)
+ - specVersion 3.0 ([#522](https://github.com/SAP/ui5-project/issues/522)) [`c5070e5`](https://github.com/SAP/ui5-project/commit/c5070e55d92ced4326cd7611caf3ec9a3da9e7ed)
+ - Introduce SpecificationVersion class ([#431](https://github.com/SAP/ui5-project/issues/431)) [`e57842b`](https://github.com/SAP/ui5-project/commit/e57842b06397a5b36e6373df97f7b7bb91f09741)
+ - **TaskRunner:** Provide taskName and logger instance to custom tasks [`36cd2d8`](https://github.com/SAP/ui5-project/commit/36cd2d83f9a6a92cbd28619d8a25c0ba3f732117)
+ - **TaskUtil:** Add resourceFactory API to v3 interface [`2e863cf`](https://github.com/SAP/ui5-project/commit/2e863cfaf9f8924d0c87fe9dfe01568c1fd979c8)
+ - **TaskUtil:** Add getProject/getDependencies API to interface [`51f2949`](https://github.com/SAP/ui5-project/commit/51f29493f57f094396776bb2686c8a74e8901a7f)
+- `@ui5/builder`:
+ - Support ES2022 language features ([#848](https://github.com/SAP/ui5-builder/issues/848)) [`f9b8457`](https://github.com/SAP/ui5-builder/commit/f9b845726731a0e02ec4a499e2a1a82a639174a8)
+ - **jsdoc:** Support destructuring of enums for defaultValue ([#775](https://github.com/SAP/ui5-builder/issues/775)) [`523f365`](https://github.com/SAP/ui5-builder/commit/523f365cb917997c5031d245309c21e9e4b3e311)
+ - **builder:** Improve support for ES6+ syntax ([#774](https://github.com/SAP/ui5-builder/issues/774)) [`90385fe`](https://github.com/SAP/ui5-builder/commit/90385feb7cea1e5b864cff035b01263a492972a9)
+ - **jsdoc:** Improve support for ES6+ syntax ([#785](https://github.com/SAP/ui5-builder/issues/785)) [`187a6a3`](https://github.com/SAP/ui5-builder/commit/187a6a35000145d70bf41e0d8b724e5ea8d8dc78)
+ - **generateThemeDesignerResources task:** Create css_variables.less ([#730](https://github.com/SAP/ui5-builder/issues/730)) [`34e69be`](https://github.com/SAP/ui5-builder/commit/34e69be95fc8ec1961b24b7e2580c2c993d814d3)
+ - **builder:** Add cssVariables option ([#728](https://github.com/SAP/ui5-builder/issues/728)) [`30d58e1`](https://github.com/SAP/ui5-builder/commit/30d58e1081c1bdc665f13952ecbe5c400b5f4ed7)
+ - Generate source maps for bundles ([#695](https://github.com/SAP/ui5-builder/issues/695)) [`8a20c42`](https://github.com/SAP/ui5-builder/commit/8a20c4257a1ebe4d613b0595be93cd45d900f580)
+ - **replaceVersion/Copyright:** Also process test-resources ([#693](https://github.com/SAP/ui5-builder/issues/693)) [`a0d4bc2`](https://github.com/SAP/ui5-builder/commit/a0d4bc2a80d61e042786207af4bdbda6c3ddfe31)
+ - Support ES2022 language features [`e749b6a`](https://github.com/SAP/ui5-builder/commit/e749b6ae0838f923b27dd0d7d34da2174c433f5f)
+ - Add minify task and processor ([#666](https://github.com/SAP/ui5-builder/issues/666)) [`a3af604`](https://github.com/SAP/ui5-builder/commit/a3af604ff0a12fb9241dcd105cf0aec8d718a299)
+- `@ui5/server`:
+ - **MiddlewareUtil:** Add getProject/getDependencies/resourceFactory API to interface ([#547](https://github.com/SAP/ui5-server/issues/547)) [`ab28f78`](https://github.com/SAP/ui5-server/commit/ab28f789ba929ef1319b6e562267e9717cc9937b)
+- `@ui5/fs`:
+ - Add Link-reader and WriterCollection [`a0e5cf3`](https://github.com/SAP/ui5-fs/commit/a0e5cf3ef86a4b0cdc817d08963ed6574740f1bc)
+ - Introduce Readers "Filter" and "Transformer" ([#331](https://github.com/SAP/ui5-fs/issues/331)) [`f46e6d1`](https://github.com/SAP/ui5-fs/commit/f46e6d1b9aed5858f2d72b10b18635de6ed1f1e0)
+- `@ui5/logger`:
+ - Add new log level "perf" [`acf0c71`](https://github.com/SAP/ui5-logger/commit/acf0c717612f440ea7a114e757c05d358ae523a7)
+
+### Bug Fixes
+- `@ui5/project`:
+ - **ProjectBuilder:** Fix verbose logging for already built projects [`f04ffd2`](https://github.com/SAP/ui5-project/commit/f04ffd2c0ab0270df697c20258474ff536811476)
+ - **ProjectBuilder:** Skip build for projects that do not require to be built [`ac5f1f8`](https://github.com/SAP/ui5-project/commit/ac5f1f891255b56597e51d121329f03786338d4a)
+ - **Specification:** Fix migration for legacy projects that are not applications or libraries [`d89d804`](https://github.com/SAP/ui5-project/commit/d89d8047519ca8f162dc7a225f138ae304871ecb)
+ - Fix build manifest creation [`b1459eb`](https://github.com/SAP/ui5-project/commit/b1459eb26aa8a4b18ad84a369c122c114d64b64b)
+- `@ui5/builder`:
+ - Avoid redundant bundle creation ([#741](https://github.com/SAP/ui5-builder/issues/741)) [`13c8405`](https://github.com/SAP/ui5-builder/commit/13c840585946401d238936dfa38a6f70a73e9ed0)
+ - **JSModuleAnalyzer:** Fix detection of bundle name ([#705](https://github.com/SAP/ui5-builder/issues/705)) [`aaeafd4`](https://github.com/SAP/ui5-builder/commit/aaeafd4a1fd194dd08e5ae47c29d90f0b4c7d197)
+ - **generateResourcesJson:** Add raw-module info for debug bundles ([#736](https://github.com/SAP/ui5-builder/issues/736)) [`3b918e8`](https://github.com/SAP/ui5-builder/commit/3b918e83bfd38342778ecd4c58e648e99ad7cffc)
+ - **LibraryBuilder:** Align task order of "generateComponentPreload" [`aea061d`](https://github.com/SAP/ui5-builder/commit/aea061d9d6c2ac0c11484dcc08bdcda23ab62986)
+ - **LocatorResourcePool:** Wait for resources in prepare step ([#719](https://github.com/SAP/ui5-builder/issues/719)) [`1b7f93f`](https://github.com/SAP/ui5-builder/commit/1b7f93f4988340d7a6575be3191a02e6c295ebd0)
+ - **XMLTemplateAnalyzer:** Analyze core:require of FragmentDefinition [`af075ed`](https://github.com/SAP/ui5-builder/commit/af075edf784d9f1ba162a34f0bf150dbcbc0f479)
+ - **Bundler:** Ensure reproducibility for bundles with multiple parts ([#689](https://github.com/SAP/ui5-builder/issues/689)) [`6f4588b`](https://github.com/SAP/ui5-builder/commit/6f4588b3eb687178e557ac4fb36481104f9681a0)
+ - **generateResourcesJson:** Don't list resources omitted from build result [`9608c51`](https://github.com/SAP/ui5-builder/commit/9608c5177f86494ba689d2e799b4378fec9ed6fa)
+ - **generateResourcesJson:** Analyze debug bundles ([#669](https://github.com/SAP/ui5-builder/issues/669)) [`f27513a`](https://github.com/SAP/ui5-builder/commit/f27513a259b30d39e260790781b6d435b4ab088b)
+ - **Bundler:** Sort raw modules by default [`0e11b69`](https://github.com/SAP/ui5-builder/commit/0e11b6965a1d2e63a96e9b738e38975b5ac755bc)
+- `@ui5/fs`:
+ - **FileSystem Adapter:** Use fs.copy / Skip writing when resource is unchanged ([#370](https://github.com/SAP/ui5-fs/issues/370)) [`9ac6a39`](https://github.com/SAP/ui5-fs/commit/9ac6a39f3cb72e02c2a1298b07c4676a0ee92377)
+ - Allow resource migration ([#407](https://github.com/SAP/ui5-fs/issues/407)) [`1722d71`](https://github.com/SAP/ui5-fs/commit/1722d71b78184cae0dfb092fd3d4c4156924dc28)
+
+## Details
+### Breaking Changes
+Support for older Node.js and npm releases has been dropped for all UI5 Tooling modules.
+Only Node.js v16.18.0 and npm v8 or higher are supported.
+
+All packages have been transformed to ES Modules. Therefore modules are no longer provides a CommonJS exports.
+If your project uses CommonJS, it needs to be converted to ES Modules or use a dynamic import for consuming UI5 Tooling modules.
+
+For more information see also:
+- https://sap.github.io/ui5-tooling/updates/migrate-v3/
+- https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
+
+### @ui5/cli
+- Removed CLI option `--translator`. Use new option `--dependency-definition` to provide a file with
+ static dependency information
+- Removed `ui5 build dev` command
+- Refactored `ui5 tree`: Removed `--full`, `--json` and `--dedupe` options
+
+#### @ui5/project
+- normalizer and projectTree APIs have been removed. Use generateProjectGraph instead
+- Going forward only specification versions 2.0 and higher are supported
+ - In case a legacy specification version is detected, an automatic, transparent migration is attempted.
+- Build:
+ - The "dev" build mode has been removed
+ - The task "generateVersionInfo" is no longer executed for application projects by default. You may enable it again using the includedTasks parameter
+
+#### @ui5/builder
+The `jsdocGenerator` processor and the corresponding `generateJsdoc` task will now throw an error when JSDoc reports an error (exit code != 0). This will also fail the build when running `ui5 build jsdoc`.
+
+The manifestBundler processor and generateManifestBundle task has been removed because it is no longer required for the HTML5 repository in Cloud Foundry.
+
+- builder.js has been removed. Use ui5-project builder instead
+- Tasks now rely on Project instances being available on Resources (see https://github.com/SAP/ui5-fs/pull/381)
+- TaskRepository#addTask has been removed. Custom tasks need to be added to the project graph instead
+- TaskUtil#get/set/clearTag now requires a Project instance to be provided. Path strings are no longer sufficient and will cause an exception to be thrown
+
+For library projects, the task "generateComponentPreload" is now executed after tasks "generateLibraryManifest" and "generateManifestBundle" instead of before them.
+
+The following tasks have been removed:
+
+- createDebugFiles
+- uglify
+
+The following processors have been removed:
+
+- debugFileCreator
+- resourceCopier
+- uglifier
+
+As a replacement, the new 'minify' task and 'minifier' processor can be used.
+
+Note: The minify task is executed earlier, before the bundling process takes place. Existing 'beforeTask' and 'afterTask' configuration of custom tasks might need to be adapted to cater for this change.
+
+#### @ui5/server
+This removes the "/proxy" endpoint and the corresponding "connectUi5Proxy" middleware from the standard ui5-server. Internally, this middleware made use of the connect-openui5 proxy implementation (https://github.com/SAP/connect-openui5#proxy).
+
+More sophisticated proxy solutions for ui5-server are already available in the form of custom middleware extensions from the UI5-community.
+
+The UI5 Team might provide a dedicated custom middleware extension, with similar functionality, in the future.
+
+- Server now requires a Project Graph instance instead.
+- Standard middleware now rely on Project instances being available on Resources (see https://github.com/SAP/ui5-fs/pull/381)
+- MiddlewareRepository#addMiddleware has been removed. Custom middleware need to be added to the project graph instead
+
+#### @ui5/fs
+An error is thrown when a resource shall be written to an adapter where the path of the resource does not starts with the virtual base path defined in the adapter.
+
+Resources stored in the adapters can not be modified by reference anymore. All modifications need to be persisted by using the #write method in order to be reflected in the adapter.1d908bbc7ff3ecc99d99c
+
+### @ui5/logger
+The @ui5/logger got refactored and as a result its API went public. Remove the usage of npmlog and refactor @ui5/logger modules to emit log events which are then caught in dedicated handlers. This is somewhat inspired by npm's proc-log module.
+
+This breaking change removes capabilities that are likely to change and should not be part of a public API.
+This will ensure that later changes to the module can be done in a compatible manner.
+
+Relevant changes:
+
+- Restrict log-methods to two argument only. The use of placeholders like '%s' is no longer supported.
+ A warning will be logged if more than two argument is supplied. Placeholders will be replaced with a deprecation message. We suggest the use of template literals.
+- Deprecate #getGroupLogger method. Calling it throws an error.
+ It will be removed in one of the next patch releases
+- Deprecate #setShowProgress method. Calling it throws an error.
+ It will be removed in one of the next patch releases
+- Remove GroupLogger and TaskLogger classes. Similar functionality might be re-added in a later release.
+
+
+
+## [v2.14.17] - 2022-12-13
+
+
+## [v2.14.16] - 2022-11-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.4.0 to 2.4.1 [`92fb840`](https://github.com/SAP/ui5-cli/commit/92fb840f77bf3a8669bee11ed9e22dbef240d1d3)
+
+
+
+## [v2.14.15] - 2022-11-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.8 to 2.11.9 [`803f8cc`](https://github.com/SAP/ui5-cli/commit/803f8ccb9f3daf3523872f9a4bbf0bda5e3c7f02)
+
+
+
+## [v2.14.14] - 2022-10-28
+### Bug Fixes
+- **SyntaxError:** Unexpected token '.' in Node.js v12 [`bab2057`](https://github.com/SAP/ui5-cli/commit/bab2057e184a2072f9b596565d9690b6e39b109d)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.7 to 2.11.8 [`1f5e517`](https://github.com/SAP/ui5-cli/commit/1f5e5173d0ca594ea4a34b97b0a760c67a9664a9)
+
+
+
+## [v2.14.13] - 2022-10-20
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.6 to 2.11.7 [`d3b3f06`](https://github.com/SAP/ui5-cli/commit/d3b3f0626e0c03d999b150338d4112d3c875e02d)
+
+
+
+## [v2.14.12] - 2022-10-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.5 to 2.11.6 [`f695e27`](https://github.com/SAP/ui5-cli/commit/f695e2733395599271b1a1059860c519851c7fe7)
+
+
+
+## [v2.14.11] - 2022-09-05
+### Bug Fixes
+- Upgrade update-notifier to solve security vulnerabilities ([#533](https://github.com/SAP/ui5-cli/issues/533)) [`5b7cfcf`](https://github.com/SAP/ui5-cli/commit/5b7cfcf62c37492c4072c69f400512ef59aab502)
+
+
+
+## [v2.14.10] - 2022-07-25
+
+
+## [v2.14.9] - 2022-05-04
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.4 to 2.11.5 [`aa90039`](https://github.com/SAP/ui5-cli/commit/aa9003933bb6f5e71e9ce968ab5cc6202f805256)
+
+
+
+## [v2.14.8] - 2022-04-14
+
+
+## [v2.14.7] - 2022-03-25
+
+
+## [v2.14.6] - 2022-02-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.3 to 2.11.4 [`f8ce36c`](https://github.com/SAP/ui5-cli/commit/f8ce36ca504c1021c3e3825a6762dda29f7ea74d)
+
+
+
+## [v2.14.5] - 2022-02-17
+
+
+## [v2.14.4] - 2022-01-24
+
+
+## [v2.14.3] - 2022-01-19
+
+
+## [v2.14.2] - 2021-12-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.2 to 2.11.3 [`ebe6377`](https://github.com/SAP/ui5-cli/commit/ebe6377e347475cf2219ea97deee44fd617f6d7e)
+
+
+
+## [v2.14.1] - 2021-11-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.1 to 2.11.2 [`f389b00`](https://github.com/SAP/ui5-cli/commit/f389b00c95ce81ad1993fef2bd7b4ad79d523be1)
+
+
+
+## [v2.14.0] - 2021-10-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.5.0 to 2.6.0 [`2c42bba`](https://github.com/SAP/ui5-cli/commit/2c42bba826add655dd0bf44d4c78ff72258d10b2)
+- Bump [@ui5](https://github.com/ui5)/server from 2.3.1 to 2.4.0 [`063b2f7`](https://github.com/SAP/ui5-cli/commit/063b2f77c936b90f1a2cd9febb7a5aed0f17fa20)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.11.0 to 2.11.1 [`11a0f5a`](https://github.com/SAP/ui5-cli/commit/11a0f5a391ca9e629b52b3046560678a8afeaf16)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.10.0 to 2.11.0 [`6f13917`](https://github.com/SAP/ui5-cli/commit/6f139171d3bd46da7bdb1c4c8015589e60fa14f6)
+
+
+
+## [v2.13.0] - 2021-10-05
+### Bug Fixes
+- Allow Node.js pre-release versions ([#458](https://github.com/SAP/ui5-cli/issues/458)) [`f6351c6`](https://github.com/SAP/ui5-cli/commit/f6351c663975f4ea14f08fa9a655bb6bf0447080)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.5 to 2.10.0 [`1d6a0f4`](https://github.com/SAP/ui5-cli/commit/1d6a0f423fc3fa782b341614d562c04292f00e1b)
+
+
+
+## [v2.12.1] - 2021-08-25
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.4 to 2.9.5 [`e25a630`](https://github.com/SAP/ui5-cli/commit/e25a630b03d0d68566b200e1346e25ed77f34c44)
+
+
+
+## [v2.12.0] - 2021-07-23
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.4.0 to 2.5.0 [`0b4c2fb`](https://github.com/SAP/ui5-cli/commit/0b4c2fbc840024e30c1f85de441c5908a4774518)
+- Bump [@ui5](https://github.com/ui5)/server from 2.3.0 to 2.3.1 [`ffbd9a5`](https://github.com/SAP/ui5-cli/commit/ffbd9a5bc0e9ac0d3dca4f66d0ab5a7758aaec3a)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.3 to 2.9.4 [`dfeb74e`](https://github.com/SAP/ui5-cli/commit/dfeb74ec96a5c14a500d56952f4727b1b7f0b4cd)
+
+### Features
+- Support to only build certain dependencies ([#442](https://github.com/SAP/ui5-cli/issues/442)) [`5f941f1`](https://github.com/SAP/ui5-cli/commit/5f941f1e5d3041fc94f2e9e9eed14ad44add78aa)
+
+
+
+## [v2.11.3] - 2021-07-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.10 to 2.3.0 [`1d852fc`](https://github.com/SAP/ui5-cli/commit/1d852fc5e455934fc533c99c5fa62346b33c7182)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.2 to 2.9.3 [`73036be`](https://github.com/SAP/ui5-cli/commit/73036be811572ba50c439ccc95b15110057a6a62)
+
+
+
+## [v2.11.2] - 2021-06-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.1 to 2.9.2 [`be6c9a4`](https://github.com/SAP/ui5-cli/commit/be6c9a456986f123a2e0da2d3b5b3b9d1bbf962a)
+
+
+
+## [v2.11.1] - 2021-06-08
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.9.0 to 2.9.1 [`a2a66d8`](https://github.com/SAP/ui5-cli/commit/a2a66d872b3b9c309e3ad9664a94a24577836296)
+
+
+
+## [v2.11.0] - 2021-06-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.3.1 to 2.4.0 [`f50642a`](https://github.com/SAP/ui5-cli/commit/f50642aebe9e99b958dc29048769a627c170552d)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.9 to 2.2.10 [`8670767`](https://github.com/SAP/ui5-cli/commit/86707676c179622f1b6b1b523cb29292be3dbdac)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.4 to 2.9.0 [`9e3b7ec`](https://github.com/SAP/ui5-cli/commit/9e3b7ecb033cd45b30ba7b8645cb97c19e2a34e8)
+
+
+
+## [v2.10.4] - 2021-05-17
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.3 to 2.8.4 [`7df37c1`](https://github.com/SAP/ui5-cli/commit/7df37c11d3c8194b282d9972345c8b844427ff12)
+
+
+
+## [v2.10.3] - 2021-04-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.2 to 2.8.3 [`572bac4`](https://github.com/SAP/ui5-cli/commit/572bac4a147d2e87bab9a57858637f34ef03a1ce)
+
+
+
+## [v2.10.2] - 2021-03-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.8 to 2.2.9 [`a7d3436`](https://github.com/SAP/ui5-cli/commit/a7d343696f059389709085df831f3c7f9afc8898)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.1 to 2.8.2 [`6d308da`](https://github.com/SAP/ui5-cli/commit/6d308da757dcc1d975475677b42520ab146116d0)
+
+
+
+## [v2.10.1] - 2021-03-04
+### Bug Fixes
+- `ui5 use ` should default to `latest` [`cda4b2c`](https://github.com/SAP/ui5-cli/commit/cda4b2cc29e376d92be4bc92fb7ee2a81974836a)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.3.0 to 2.3.1 [`912c6e0`](https://github.com/SAP/ui5-cli/commit/912c6e0c37e2df4a8768c0b6879aff58703d303a)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.8.0 to 2.8.1 [`baed42f`](https://github.com/SAP/ui5-cli/commit/baed42f282ec1e3cf6d42a8fed97fe81844ad8c5)
+- Bump js-yaml from 3.14.1 to 4.0.0 ([#402](https://github.com/SAP/ui5-cli/issues/402)) [`0033c52`](https://github.com/SAP/ui5-cli/commit/0033c5272b6258c95cc1f7487aa53c7e64bbe50c)
+
+
+
+## [v2.10.0] - 2021-02-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.6 to 2.3.0 [`e8c5f37`](https://github.com/SAP/ui5-cli/commit/e8c5f3781d6a7ed649ff68481eccf4f3cf4a1990)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.7 to 2.2.8 [`8325bdf`](https://github.com/SAP/ui5-cli/commit/8325bdf698d28143f1d989139f162fc57217f939)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.7.2 to 2.8.0 [`553d543`](https://github.com/SAP/ui5-cli/commit/553d5432599fa18bed7fb878856f78f294460e46)
+
+
+
+## [v2.9.3] - 2021-01-29
+
+
+## [v2.9.2] - 2021-01-29
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.7.1 to 2.7.2 [`0d0e9e9`](https://github.com/SAP/ui5-cli/commit/0d0e9e94dce8168944d2833d44073ac79318cdc5)
+
+
+
+## [v2.9.1] - 2021-01-28
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.5 to 2.2.6 [`7a6182a`](https://github.com/SAP/ui5-cli/commit/7a6182a4fe23475b074e7bec9c6feaeb08534670)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.7.0 to 2.7.1 [`9e2882e`](https://github.com/SAP/ui5-cli/commit/9e2882eca7179389227da731682bf1c9c0425617)
+
+
+
+## [v2.9.0] - 2021-01-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.6.1 to 2.7.0 [`d9f00fc`](https://github.com/SAP/ui5-cli/commit/d9f00fc68ed032be6ef614811aceccea9a947a2e)
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.4 to 2.2.5 [`62886ce`](https://github.com/SAP/ui5-cli/commit/62886ce921479a7198d658b296b66fe040cc89d9)
+
+
+
+## [v2.8.1] - 2021-01-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.6.0 to 2.6.1 [`d2d1081`](https://github.com/SAP/ui5-cli/commit/d2d1081da16b18c1a4ec78c1e09f6568f53f3c61)
+
+
+
+## [v2.8.0] - 2021-01-14
+### Bug Fixes
+- **ui5 use:** Corrupt UI5 configuration [`c207e1e`](https://github.com/SAP/ui5-cli/commit/c207e1e7318123a8801627ca80e61f59e7c73edb)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.5.1 to 2.6.0 [`711a071`](https://github.com/SAP/ui5-cli/commit/711a07120b9ed652674216f22d81c8098d790a95)
+
+
+
+## [v2.7.1] - 2020-12-18
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.5.0 to 2.5.1 [`9a208c1`](https://github.com/SAP/ui5-cli/commit/9a208c173f005178f41e343e67c61c021de71f61)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.5 to 2.0.6 [`3965d14`](https://github.com/SAP/ui5-cli/commit/3965d1442ad2e11d26f6730fdb8ff6ec7fff0172)
+
+
+
+## [v2.7.0] - 2020-12-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.5 to 2.5.0 [`9c353a6`](https://github.com/SAP/ui5-cli/commit/9c353a6327f11f016c7bd18da76b3468eca42fc6)
+
+
+
+## [v2.6.6] - 2020-11-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.4 to 2.4.5 [`10c0342`](https://github.com/SAP/ui5-cli/commit/10c03428cd0108a1c380de4abff45af1ce97ef55)
+
+
+
+## [v2.6.5] - 2020-11-25
+### Bug Fixes
+- Always log stack trace of unexpected errors [`aba4e49`](https://github.com/SAP/ui5-cli/commit/aba4e493fd5609cf17e820651be0336a7c7b3390)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.3 to 2.4.4 [`9935fed`](https://github.com/SAP/ui5-cli/commit/9935fed156f4367160b6dd9d3b2beecf1d23710b)
+
+
+
+## [v2.6.4] - 2020-11-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.6 to 2.2.7 [`bc83eac`](https://github.com/SAP/ui5-cli/commit/bc83eac65618a5cad889cea9c7518cacf9022b1e)
+
+
+
+## [v2.6.3] - 2020-11-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.3 to 2.2.4 [`7b69c21`](https://github.com/SAP/ui5-cli/commit/7b69c216f9eb5a9621ee9934e6e7224365111fe6)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.2 to 2.4.3 [`898f7de`](https://github.com/SAP/ui5-cli/commit/898f7de99e4f60067759d04818f10ea6ac544b5f)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.4 to 2.0.5 [`8281b8b`](https://github.com/SAP/ui5-cli/commit/8281b8bde7ed7175e340ca7af0b2bdb3276b0310)
+
+### Performance Improvements
+- Reduce install size by removing 'string.prototype.matchall' dependency [`cb34e84`](https://github.com/SAP/ui5-cli/commit/cb34e84db1a6212c37ca56f8fb3fa86bc496deab)
+
+
+
+## [v2.6.2] - 2020-11-04
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.1 to 2.4.2 [`60126af`](https://github.com/SAP/ui5-cli/commit/60126af947665b470b7dd2245feab0fa05ed78b6)
+
+
+
+## [v2.6.1] - 2020-11-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.4.0 to 2.4.1 [`e22e372`](https://github.com/SAP/ui5-cli/commit/e22e372119688d7b8a5862a8c2d5c166e85b3e92)
+
+
+
+## [v2.6.0] - 2020-11-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.3.0 to 2.4.0 [`2d49e9b`](https://github.com/SAP/ui5-cli/commit/2d49e9be5706d2ff0ae74587d0d91f3d1dcd2ebe)
+
+
+
+## [v2.5.0] - 2020-10-22
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.2 to 2.2.3 [`21f5bd6`](https://github.com/SAP/ui5-cli/commit/21f5bd6c7d478dd143184dcdd9b1097831c7c3c7)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.5 to 2.2.6 [`6740a0c`](https://github.com/SAP/ui5-cli/commit/6740a0c424e00a3be23fb8aeb1e1570f9aa53b67)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.2.1 to 2.3.0 [`8574924`](https://github.com/SAP/ui5-cli/commit/8574924c1b8e434aff0fa42c0a66f4ef2275fc97)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.3 to 2.0.4 [`3c14bd4`](https://github.com/SAP/ui5-cli/commit/3c14bd403b1c48da32b5e1ae8a9dcbf3da12f7b8)
+- Bump [@ui5](https://github.com/ui5)/logger from 2.0.0 to 2.0.1 [`a401bfd`](https://github.com/SAP/ui5-cli/commit/a401bfd768412453148323f19e8f773cb367ee96)
+
+
+
+## [v2.4.5] - 2020-10-06
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.4 to 2.2.5 [`80edb1c`](https://github.com/SAP/ui5-cli/commit/80edb1c403025ee2d3a3542c3d1c6530cebb6832)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.2.0 to 2.2.1 [`f464793`](https://github.com/SAP/ui5-cli/commit/f4647938ee327dcebda9eafaf318c0296d6a0d4a)
+
+
+
+## [v2.4.4] - 2020-09-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.1 to 2.2.2 [`3755911`](https://github.com/SAP/ui5-cli/commit/3755911b0b6818129079cf138409a3827f1d2c29)
+
+
+
+## [v2.4.3] - 2020-09-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.3 to 2.2.4 [`1d033a4`](https://github.com/SAP/ui5-cli/commit/1d033a4ab519e688dac18aa2dc2888b8695254aa)
+
+
+
+## [v2.4.2] - 2020-09-02
+### Bug Fixes
+- Allow use of `--no-update-notifier` flag [`a34b58c`](https://github.com/SAP/ui5-cli/commit/a34b58c260ecb3778eb737d983b4d6b0a5829511)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.2.0 to 2.2.1 [`1f735d9`](https://github.com/SAP/ui5-cli/commit/1f735d922de587ed7a876eb44db4aa32dd2dad86)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.2 to 2.2.3 [`5170730`](https://github.com/SAP/ui5-cli/commit/5170730fa1e3b1275856a9e7346def42257d012a)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.1.0 to 2.2.0 [`b164a69`](https://github.com/SAP/ui5-cli/commit/b164a69a8df5b3270dc06755c1e2b3f59f715689)
+
+
+
+## [v2.4.1] - 2020-08-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.2 to 2.0.3 [`2189686`](https://github.com/SAP/ui5-cli/commit/218968643d646443815e9e1206c40aac7edd3e2f)
+
+
+
+## [v2.4.0] - 2020-08-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.5 to 2.2.0 [`43cc824`](https://github.com/SAP/ui5-cli/commit/43cc82473e02c714586047b0a453ba8d1d0a3818)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.1 to 2.2.2 [`42f4acc`](https://github.com/SAP/ui5-cli/commit/42f4acc8545cb8a5c6db62dc1a26ba09229157e0)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.7 to 2.1.0 [`30cfbc6`](https://github.com/SAP/ui5-cli/commit/30cfbc672c62aba9ef3561336ac2bf1d5e6a470a)
+
+
+
+## [v2.3.2] - 2020-08-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.6 to 2.0.7 [`fba5633`](https://github.com/SAP/ui5-cli/commit/fba56332a2a8395da2459dec40f81e04ca80dd9f)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.1 to 2.0.2 [`d584699`](https://github.com/SAP/ui5-cli/commit/d584699855fc44d59ff67cc5720dda3733f3cc13)
+
+
+
+## [v2.3.1] - 2020-07-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.5 to 2.0.6 [`12dd9f6`](https://github.com/SAP/ui5-cli/commit/12dd9f6fc2d844a9425c6baf2822ac5b956a571e)
+
+
+
+## [v2.3.0] - 2020-07-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.4 to 2.1.5 [`0740fd1`](https://github.com/SAP/ui5-cli/commit/0740fd19d8530478820d5638db4e5eb0170b9ac1)
+- Bump [@ui5](https://github.com/ui5)/server from 2.2.0 to 2.2.1 [`139b59a`](https://github.com/SAP/ui5-cli/commit/139b59a3237bf66e8a851fbcf51d6a20b48dcc10)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.4 to 2.0.5 [`4c28263`](https://github.com/SAP/ui5-cli/commit/4c2826320ff8ac9af34fa417121f2cdcacb042aa)
+- Bump [@ui5](https://github.com/ui5)/server from 2.1.0 to 2.2.0 [`b5bf1cb`](https://github.com/SAP/ui5-cli/commit/b5bf1cb8e73dc563ffb42397cfa679b5d97202ee)
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.3 to 2.1.0 [`bd26b2b`](https://github.com/SAP/ui5-cli/commit/bd26b2bb5ed2824a1d0be1c8a18ffa17f4e4af22)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.3 to 2.0.4 [`a20233e`](https://github.com/SAP/ui5-cli/commit/a20233ea8f88bf41b09990c53a3911c558e62dfa)
+
+### Features
+- **ui5 serve:** Add serve-csp-reports option ([#339](https://github.com/SAP/ui5-cli/issues/339)) [`063e7a5`](https://github.com/SAP/ui5-cli/commit/063e7a512d474353e2d86dd77453b10935b4bc05)
+
+
+
+## [v2.2.6] - 2020-05-29
+### Bug Fixes
+- **ui5 use:** Allow using versions according to Semantic Versioning [`d7a9363`](https://github.com/SAP/ui5-cli/commit/d7a9363ac10f167b7e5ebc1c5a7384f0fc6abbcc)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.3 to 2.1.4 [`c584f11`](https://github.com/SAP/ui5-cli/commit/c584f114b7b8ba936399360832296e62e485977c)
+
+
+
+## [v2.2.5] - 2020-05-27
+
+
+## [v2.2.4] - 2020-05-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.2 to 2.0.3 [`b0ef029`](https://github.com/SAP/ui5-cli/commit/b0ef0291cdc64ddbb1cb459fff4582f7c0db326e)
+
+
+
+## [v2.2.3] - 2020-05-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.2 to 2.1.3 [`e58febb`](https://github.com/SAP/ui5-cli/commit/e58febb866a6413407723608b9049be78afaa1ef)
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.2 to 2.0.3 [`a73b7e3`](https://github.com/SAP/ui5-cli/commit/a73b7e3af01a488f5c9e7c7b68211ca2a8cda3e8)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.1 to 2.0.2 [`2c53f21`](https://github.com/SAP/ui5-cli/commit/2c53f21dc83531645f67a08182b83b5042f4cc30)
+
+
+
+## [v2.2.2] - 2020-05-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.1 to 2.1.2 [`191e621`](https://github.com/SAP/ui5-cli/commit/191e6211b5ff9e4edb8c32f71d7509e9e755e596)
+
+
+
+## [v2.2.1] - 2020-05-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.1.0 to 2.1.1 [`14a19d9`](https://github.com/SAP/ui5-cli/commit/14a19d98bd35635b87ada4c58cd79fe44f3c5a67)
+
+
+
+## [v2.2.0] - 2020-05-05
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.4 to 2.1.0 [`dce7fd2`](https://github.com/SAP/ui5-cli/commit/dce7fd2f00731d9fac016695cf7775692cdf6cd9)
+
+
+
+## [v2.1.0] - 2020-04-30
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.3 to 2.0.4 [`0bee0a0`](https://github.com/SAP/ui5-cli/commit/0bee0a0a818168263d925b49af3d8008f1c66cc3)
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.1 to 2.0.2 [`f7ed0cc`](https://github.com/SAP/ui5-cli/commit/f7ed0ccee6cc20b0a4c2aade78a89ffcacc267e1)
+- Bump [@ui5](https://github.com/ui5)/builder from 2.0.0 to 2.0.1 [`e70a426`](https://github.com/SAP/ui5-cli/commit/e70a42692c755317f6f7e612725550ef834e4d07)
+- Bump [@ui5](https://github.com/ui5)/fs from 2.0.0 to 2.0.1 [`3b50590`](https://github.com/SAP/ui5-cli/commit/3b5059055b1dcc69d42b128cccdc3251c7c24b49)
+
+### Features
+- Add "ui5 remove" command ([#327](https://github.com/SAP/ui5-cli/issues/327)) [`6c6be0d`](https://github.com/SAP/ui5-cli/commit/6c6be0d3941507c965dd303f3964f4cf5a77731c)
+
+
+
+## [v2.0.3] - 2020-04-15
+### Bug Fixes
+- **ui5 use/add:** Fix updating ui5.yaml file [`225f4ab`](https://github.com/SAP/ui5-cli/commit/225f4aba7c60439c4f3d7554cb918a2ba03ce1bd)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 2.0.0 to 2.0.1 [`2d81aa8`](https://github.com/SAP/ui5-cli/commit/2d81aa814f9008e6cf4e38a5d5a9ca2d2d00623a)
+
+
+
+## [v2.0.2] - 2020-04-02
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.2 to 2.0.3 [`1aaa9c1`](https://github.com/SAP/ui5-cli/commit/1aaa9c19a1b3a90e9df27f27f8c9b0f160902945)
+
+
+
+## [v2.0.1] - 2020-04-01
+### Bug Fixes
+- **npm-shrinkwrap.json:** Add additional dependencies [`a6c88f7`](https://github.com/SAP/ui5-cli/commit/a6c88f79a297602d579dd68a136c571809152582)
+
+
+
+## [v2.0.0] - 2020-04-01
+### Breaking Changes
+- Require Node.js >= 10 [`e0916ec`](https://github.com/SAP/ui5-cli/commit/e0916ec85315f6370af1b6fbc4ba5ff99f9c2c49)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.1 to 2.0.2 [`7539675`](https://github.com/SAP/ui5-cli/commit/7539675648581f3c36b21da67a1c4da12a10c763)
+- Bump [@ui5](https://github.com/ui5)/project from 2.0.0 to 2.0.1 [`2f8fbe1`](https://github.com/SAP/ui5-cli/commit/2f8fbe1b5390f6f90bf76ad107ee3f7547a7519d)
+- Bump [@ui5](https://github.com/ui5)/project from 1.2.0 to 2.0.0 [`f18f07c`](https://github.com/SAP/ui5-cli/commit/f18f07cc11f54fb936b582460d4b3ef8a844111a)
+- Bump [@ui5](https://github.com/ui5)/server from 1.6.0 to 2.0.0 [`f514cc5`](https://github.com/SAP/ui5-cli/commit/f514cc538760b6ee7a54220a2556acc8a89434b0)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.10.1 to 2.0.0 [`eee43a6`](https://github.com/SAP/ui5-cli/commit/eee43a64f6b8523ffb381a47cafc416f9152d989)
+- Bump [@ui5](https://github.com/ui5)/fs from 1.1.2 to 2.0.0 [`68f69b7`](https://github.com/SAP/ui5-cli/commit/68f69b74dd2d8edcf1d145f7d7e9398136b537f4)
+- Bump [@ui5](https://github.com/ui5)/logger from 1.0.2 to 2.0.0 [`847193d`](https://github.com/SAP/ui5-cli/commit/847193d8a56c9401dfd680fe84fd99747b349ce9)
+
+### Features
+- Add "ui5 use/add" commands ([#315](https://github.com/SAP/ui5-cli/issues/315)) [`920fbfc`](https://github.com/SAP/ui5-cli/commit/920fbfc5ea27f689aeb38beb6540c41838225c8d)
+- Add --framework-version option ([#306](https://github.com/SAP/ui5-cli/issues/306)) [`ae7932b`](https://github.com/SAP/ui5-cli/commit/ae7932bb36b68f3836df285ab0040083ed914c2f)
+
+### BREAKING CHANGE
+
+Support for older Node.js releases has been dropped.
+Only Node.js v10 or higher is supported.
+
+
+
+## [v1.14.0] - 2020-02-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.4 to 1.6.0 [`ece1295`](https://github.com/SAP/ui5-cli/commit/ece1295083e6530701b63a0c77f475d40700e998)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.10.0 to 1.10.1 [`fadd1ee`](https://github.com/SAP/ui5-cli/commit/fadd1ee5ade74aa236f6f8671bca8ca0b934e697)
+
+
+
+## [v1.13.1] - 2020-01-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.2 to 1.5.3 [`4e43b04`](https://github.com/SAP/ui5-cli/commit/4e43b04732ae236fb14d3e55afd95e9f229581d0)
+
+
+
+## [v1.13.0] - 2020-01-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.1.1 to 1.2.0 [`af1b153`](https://github.com/SAP/ui5-cli/commit/af1b153506e5a668178d227ea9686a266675bb64)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.8.0 to 1.9.0 [`166d247`](https://github.com/SAP/ui5-cli/commit/166d247fb94f4394a4fa33afe4ad6d75cbee58f4)
+
+
+
+## [v1.12.2] - 2019-12-16
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.1 to 1.5.2 [`4ef70a7`](https://github.com/SAP/ui5-cli/commit/4ef70a78f97bd2472858cd08cfdf8814cb48256f)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.7.1 to 1.8.0 [`4d0cd36`](https://github.com/SAP/ui5-cli/commit/4d0cd36e44a887d41f418e7b784c363b024a5def)
+
+
+
+## [v1.12.1] - 2019-11-19
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.5.0 to 1.5.1 [`7a07a2e`](https://github.com/SAP/ui5-cli/commit/7a07a2e4fe7491295c2228e53da30d0e7051b962)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.7.0 to 1.7.1 [`ecbfad1`](https://github.com/SAP/ui5-cli/commit/ecbfad1afdf726b76bef09c4e604d91e1eb7690d)
+
+
+
+## [v1.12.0] - 2019-11-07
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.1.0 to 1.1.1 [`abca385`](https://github.com/SAP/ui5-cli/commit/abca38566c5728f896d5be880fcb24f795b0b11c)
+- Bump [@ui5](https://github.com/ui5)/server from 1.4.0 to 1.5.0 [`abf954b`](https://github.com/SAP/ui5-cli/commit/abf954b2b1224353b5c7a09b37394fc53562cbfc)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.6.1 to 1.7.0 [`f482702`](https://github.com/SAP/ui5-cli/commit/f482702f8a941f2c17490d67a74ac97486dce811)
+
+### Features
+- **serve:** Add '--simple-index' parameter ([#265](https://github.com/SAP/ui5-cli/issues/265)) [`dbe195e`](https://github.com/SAP/ui5-cli/commit/dbe195e8c81a8e4e7ab2c0b8d08ba6890dd5311d)
+
+
+
+## [v1.11.1] - 2019-10-30
+### Bug Fixes
+- Fix 'ui5 tree' output [`a64de74`](https://github.com/SAP/ui5-cli/commit/a64de744eec019094d11dec491f73cfac923a541)
+
+
+
+## [v1.11.0] - 2019-10-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.3.0 to 1.4.0 [`07f4719`](https://github.com/SAP/ui5-cli/commit/07f4719d488ba96800860fd780a9e08f6902ccb8)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.3 to 1.6.1 [`6d46c54`](https://github.com/SAP/ui5-cli/commit/6d46c545b3d9c347d2f6501f962acdb6d67761cc)
+- Bump [@ui5](https://github.com/ui5)/logger from 1.0.1 to 1.0.2 [`0394f1a`](https://github.com/SAP/ui5-cli/commit/0394f1afcbb8b653647834dce0c20a3e874eaeb9)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.2 to 1.5.3 [`0eee47f`](https://github.com/SAP/ui5-cli/commit/0eee47f273d8a9b5465659647319bf003ffa0399)
+
+### Features
+- **CLI:** Improve error reporting [`160b8f7`](https://github.com/SAP/ui5-cli/commit/160b8f76b70b50d3e03494ef98e140e1ef8c4d8c)
+
+
+
+## [v1.10.0] - 2019-10-09
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.1 to 1.5.2 [`cf2f4a9`](https://github.com/SAP/ui5-cli/commit/cf2f4a9dc813fe8452820b484b4abae79ee5f342)
+
+### Features
+- Add server settings [`3638ed7`](https://github.com/SAP/ui5-cli/commit/3638ed71411d0c2882a8a145113a484d16eff56b)
+
+
+
+## [v1.9.0] - 2019-09-05
+### Features
+- **ui5 build:** Add --clean-dest option [`fe60d04`](https://github.com/SAP/ui5-cli/commit/fe60d041c374494c58136435d7761e8ee957ce7b)
+
+
+
+## [v1.8.1] - 2019-09-04
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.5.0 to 1.5.1 [`1346031`](https://github.com/SAP/ui5-cli/commit/13460317cf32afc8122486d6b086bb1e61451b99)
+
+
+
+## [v1.8.0] - 2019-09-02
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.4.2 to 1.5.0 [`3de07b2`](https://github.com/SAP/ui5-cli/commit/3de07b2a9c7b804519de3680dba2e80198cfbc62)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.4.1 to 1.4.2 [`f2d1ff0`](https://github.com/SAP/ui5-cli/commit/f2d1ff0d98da460c564450ccb8a70bde094bc229)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.4.0 to 1.4.1 [`e5dcc5f`](https://github.com/SAP/ui5-cli/commit/e5dcc5fe797148008e96aabdb7e9d5eead65fefc)
+
+
+
+## [v1.7.0] - 2019-08-01
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.2.0 to 1.3.0 [`c4db860`](https://github.com/SAP/ui5-cli/commit/c4db8607130efdbecece47938a6d81f917681a91)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.3 to 1.4.0 [`cfbb26b`](https://github.com/SAP/ui5-cli/commit/cfbb26b00cb01c8a1bf211e7e81f902163d9600f)
+
+### Features
+- Log CLI version when using --verbose option [`c143a85`](https://github.com/SAP/ui5-cli/commit/c143a85d615f7e493b2bcaa98422707e3cf49e5b)
+
+
+
+## [v1.6.0] - 2019-07-11
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.3 to 1.1.0 [`659f31e`](https://github.com/SAP/ui5-cli/commit/659f31e42880a2367a79cae5ca4aee2f03d3f227)
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.3 to 1.2.0 [`ce69e24`](https://github.com/SAP/ui5-cli/commit/ce69e2434963dbacc4d4e834c4e00ecfaa89e9a6)
+
+
+
+## [v1.5.5] - 2019-07-01
+### Bug Fixes
+- **serve:** Create SSL certificate in user homedir [`48bdd06`](https://github.com/SAP/ui5-cli/commit/48bdd06bfcec3063ba046b37be76c80139458779)
+
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.2 to 1.3.3 [`43d4fd7`](https://github.com/SAP/ui5-cli/commit/43d4fd7c634e869de985ea48c4f77d25c9bc53bc)
+- Bump [@ui5](https://github.com/ui5)/fs from 1.1.1 to 1.1.2 [`5a0ece1`](https://github.com/SAP/ui5-cli/commit/5a0ece130af8164befa9e84d4494d69704cb5c0e)
+
+
+
+## [v1.5.4] - 2019-06-25
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.2 to 1.0.3 [`3b0a8f7`](https://github.com/SAP/ui5-cli/commit/3b0a8f7b96de5621e3b72c9ced579104e8750464)
+
+
+
+## [v1.5.3] - 2019-06-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.2 to 1.1.3 [`4dc552f`](https://github.com/SAP/ui5-cli/commit/4dc552fc84e79b3c4b2b4d6e6a08426b334b430c)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.1 to 1.3.2 [`98f17f1`](https://github.com/SAP/ui5-cli/commit/98f17f1c4d9d993ddbfb9195f46172fc4f777296)
+
+
+
+## [v1.5.2] - 2019-06-18
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/fs from 1.1.0 to 1.1.1 [`fd5f550`](https://github.com/SAP/ui5-cli/commit/fd5f55064c1600dd92070c7ed82ab6a0c0539d57)
+
+
+
+## [v1.5.1] - 2019-06-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.3.0 to 1.3.1 [`d1c8814`](https://github.com/SAP/ui5-cli/commit/d1c8814a577d9065e070022c1bb03417cde2b8bc)
+
+
+
+## [v1.5.0] - 2019-06-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.1 to 1.1.2 [`1d54bd5`](https://github.com/SAP/ui5-cli/commit/1d54bd53cf8bd24b5df30328a267c0ef3c8b110a)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.3 to 1.3.0 [`82ef6c1`](https://github.com/SAP/ui5-cli/commit/82ef6c10f92648e76da8855b1777df39df535805)
+- Bump [@ui5](https://github.com/ui5)/fs from 1.0.2 to 1.1.0 [`3f0ce7d`](https://github.com/SAP/ui5-cli/commit/3f0ce7d6cd9dbf1cbb6b38a9a55fdd47bf45383a)
+
+
+
+## [v1.4.4] - 2019-05-15
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.2 to 1.2.3 [`1f8e911`](https://github.com/SAP/ui5-cli/commit/1f8e9114db3701bac071d09477837940ccba0cad)
+
+
+
+## [v1.4.3] - 2019-05-13
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.1.0 to 1.1.1 [`7e81541`](https://github.com/SAP/ui5-cli/commit/7e81541e89487acec7f57ec4ac89d181486b4909)
+
+
+
+## [v1.4.2] - 2019-05-08
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.1 to 1.2.2 [`88a1f83`](https://github.com/SAP/ui5-cli/commit/88a1f83a37e5795067687bf5cabb77bceca96e61)
+
+
+
+## [v1.4.1] - 2019-05-07
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.2.0 to 1.2.1 [`3c03878`](https://github.com/SAP/ui5-cli/commit/3c038784b263b1d1af2c47802eea7c1b48c9baae)
+
+
+
+## [v1.4.0] - 2019-04-26
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 1.0.0 to 1.1.0 [`fe03e1e`](https://github.com/SAP/ui5-cli/commit/fe03e1ec034698f213649526482c2a05c2132c92)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.1.1 to 1.2.0 [`b4747fb`](https://github.com/SAP/ui5-cli/commit/b4747fbefdab4e13173dee054bfd7b66134c65eb)
+
+### Features
+- Add 'sap-csp-policies' option to 'serve' command. ([#188](https://github.com/SAP/ui5-cli/issues/188)) [`57d5567`](https://github.com/SAP/ui5-cli/commit/57d5567b2e78a6d5ce8bbc6cae50b5d7bec80da4)
+
+
+
+## [v1.3.1] - 2019-04-24
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.1.0 to 1.1.1 [`57d10d4`](https://github.com/SAP/ui5-cli/commit/57d10d40c194b34d2eb1eb22ed820579f1ac097b)
+
+
+
+## [v1.3.0] - 2019-04-12
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.1 to 1.0.2 [`50a9b5a`](https://github.com/SAP/ui5-cli/commit/50a9b5afc19e0a79f2e1f27c3bcb8f6bd6c34c37)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.5 to 1.1.0 [`f2fe60e`](https://github.com/SAP/ui5-cli/commit/f2fe60e3913cfe4cc9058c90ee1443cdf177425d)
+
+
+
+## [v1.2.4] - 2019-04-03
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.4 to 1.0.5 [`5787d54`](https://github.com/SAP/ui5-cli/commit/5787d54a048178279de0e253332cfa845655559c)
+
+
+
+## [v1.2.3] - 2019-03-28
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.3 to 1.0.4 ([#181](https://github.com/SAP/ui5-cli/issues/181)) [`ec43aec`](https://github.com/SAP/ui5-cli/commit/ec43aec8e7677b1e45f0a06f58bb29b3766f6f04)
+
+
+
+## [v1.2.2] - 2019-03-21
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/fs from 1.0.1 to 1.0.2 ([#173](https://github.com/SAP/ui5-cli/issues/173)) [`1f70ee7`](https://github.com/SAP/ui5-cli/commit/1f70ee78a398004549bdc136371c66569ab55849)
+
+### Features
+- **Build:** Add 'jsdoc' command [`3a2f4a1`](https://github.com/SAP/ui5-cli/commit/3a2f4a16fb933429318fd34afd38ab8d9394d80c)
+
+
+
+## [v1.2.1] - 2019-02-28
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.1 to 1.0.2 ([#155](https://github.com/SAP/ui5-cli/issues/155)) [`0b3ac48`](https://github.com/SAP/ui5-cli/commit/0b3ac485cccb5833b69daf8d55f9507106d272b0)
+
+
+
+## [v1.2.0] - 2019-02-14
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/project from 1.0.0 to 1.0.1 ([#142](https://github.com/SAP/ui5-cli/issues/142)) [`c777997`](https://github.com/SAP/ui5-cli/commit/c777997034d84a8a972dbc35638df07c5f1c8c2d)
+- **Security:** Bump handlebars from 4.0.12 to 4.1.0 ([#139](https://github.com/SAP/ui5-cli/issues/139)) [`ec081b6`](https://github.com/SAP/ui5-cli/commit/ec081b61df118921cbe4f050a42cc4ecaf6596c6)
+
+### Features
+- **ui5 tree:** Add dedupe option [`91580a8`](https://github.com/SAP/ui5-cli/commit/91580a8e786a1f63365bd70617403281d5c4c8e3)
+
+
+
+## [v1.1.0] - 2019-02-05
+### Features
+- Publish npm-shrinkwrap.json [`abc5d5e`](https://github.com/SAP/ui5-cli/commit/abc5d5e322696c607adecb20a70d46542862d8ee)
+
+
+
+## [v1.0.1] - 2019-02-01
+### Dependency Updates
+- Add direct dependency to [@ui5](https://github.com/ui5)/fs [`b3eb422`](https://github.com/SAP/ui5-cli/commit/b3eb422300eac59d130548c4ee0025872adb0ce4)
+- Bump [@ui5](https://github.com/ui5)/builder from 1.0.0 to 1.0.1 ([#131](https://github.com/SAP/ui5-cli/issues/131)) [`46bae7b`](https://github.com/SAP/ui5-cli/commit/46bae7bdef2e500bf4e9953cc8cd13816edb553f)
+
+
+
+## [v1.0.0] - 2019-01-10
+### Dependency Updates
+- Bump [@ui5](https://github.com/ui5)/server from 0.2.2 to 1.0.0 ([#117](https://github.com/SAP/ui5-cli/issues/117)) [`a3c97b4`](https://github.com/SAP/ui5-cli/commit/a3c97b459aecdc9e6afb829dc380945ec221ede6)
+- Bump [@ui5](https://github.com/ui5)/builder from 0.2.9 to 1.0.0 ([#115](https://github.com/SAP/ui5-cli/issues/115)) [`b979899`](https://github.com/SAP/ui5-cli/commit/b9798990f9806c13405bc1e919e4c6a82db5e855)
+- Bump [@ui5](https://github.com/ui5)/logger from 0.2.2 to 1.0.0 ([#114](https://github.com/SAP/ui5-cli/issues/114)) [`6df410e`](https://github.com/SAP/ui5-cli/commit/6df410e808477b3b7cdbed0b2f0590fa1ece17a2)
+
+### Features
+- **ui5 init:** Use specVersion: '1.0' [`d0bfe7e`](https://github.com/SAP/ui5-cli/commit/d0bfe7ef02d9dde50ed32abb9e6e70375d3263fc)
+
+
+
+## [v0.2.9] - 2019-01-03
+
+
+## [v0.2.8] - 2018-12-19
+
+
+## [v0.2.7] - 2018-12-06
+
+
+## [v0.2.6] - 2018-11-20
+
+
+## [v0.2.5] - 2018-11-20
+### Features
+- Versions Command [`6c75777`](https://github.com/SAP/ui5-cli/commit/6c75777e9ac686d3488cafc5627842810be3afd4)
+
+
+
+## [v0.2.4] - 2018-11-17
+### Features
+- Prefer local over global CLI version ([#59](https://github.com/SAP/ui5-cli/issues/59)) [`3c2a0a8`](https://github.com/SAP/ui5-cli/commit/3c2a0a898742a118206b1009188a7d4933fe8a89)
+
+
+
+## [v0.2.3] - 2018-10-29
+
+
+## [v0.2.2] - 2018-10-10
+
+
+## [v0.2.1] - 2018-07-17
+
+
+## [v0.2.0] - 2018-07-12
+### Features
+- Add Node.js version check [`80b5bfe`](https://github.com/SAP/ui5-cli/commit/80b5bfe1d53494889c794171109321ebbd3f8d61)
+- Add update notifier [`90d03ba`](https://github.com/SAP/ui5-cli/commit/90d03ba8e86f9925b8a9c45cd72ecc28cda75eab)
+
+
+
+## [v0.1.0] - 2018-06-26
+
+
+## [v0.0.2] - 2018-06-21
+
+
+## v0.0.1 - 2018-06-06
+[v4.0.26]: https://github.com/SAP/ui5-cli/compare/v4.0.25...v4.0.26
+[v4.0.25]: https://github.com/SAP/ui5-cli/compare/v4.0.24...v4.0.25
+[v4.0.24]: https://github.com/SAP/ui5-cli/compare/v4.0.23...v4.0.24
+[v4.0.23]: https://github.com/SAP/ui5-cli/compare/v4.0.22...v4.0.23
+[v4.0.22]: https://github.com/SAP/ui5-cli/compare/v4.0.21...v4.0.22
+[v4.0.21]: https://github.com/SAP/ui5-cli/compare/v4.0.20...v4.0.21
+[v4.0.20]: https://github.com/SAP/ui5-cli/compare/v4.0.19...v4.0.20
+[v4.0.19]: https://github.com/SAP/ui5-cli/compare/v4.0.18...v4.0.19
+[v4.0.18]: https://github.com/SAP/ui5-cli/compare/v4.0.17...v4.0.18
+[v4.0.17]: https://github.com/SAP/ui5-cli/compare/v4.0.16...v4.0.17
+[v4.0.16]: https://github.com/SAP/ui5-cli/compare/v4.0.15...v4.0.16
+[v4.0.15]: https://github.com/SAP/ui5-cli/compare/v4.0.14...v4.0.15
+[v4.0.14]: https://github.com/SAP/ui5-cli/compare/v4.0.13...v4.0.14
+[v4.0.13]: https://github.com/SAP/ui5-cli/compare/v4.0.12...v4.0.13
+[v4.0.12]: https://github.com/SAP/ui5-cli/compare/v4.0.11...v4.0.12
+[v4.0.11]: https://github.com/SAP/ui5-cli/compare/v4.0.10...v4.0.11
+[v4.0.10]: https://github.com/SAP/ui5-cli/compare/v4.0.9...v4.0.10
+[v4.0.9]: https://github.com/SAP/ui5-cli/compare/v4.0.8...v4.0.9
+[v4.0.8]: https://github.com/SAP/ui5-cli/compare/v4.0.7...v4.0.8
+[v4.0.7]: https://github.com/SAP/ui5-cli/compare/v4.0.6...v4.0.7
+[v4.0.6]: https://github.com/SAP/ui5-cli/compare/v4.0.5...v4.0.6
+[v4.0.5]: https://github.com/SAP/ui5-cli/compare/v4.0.4...v4.0.5
+[v4.0.4]: https://github.com/SAP/ui5-cli/compare/v4.0.3...v4.0.4
+[v4.0.3]: https://github.com/SAP/ui5-cli/compare/v4.0.2...v4.0.3
+[v4.0.2]: https://github.com/SAP/ui5-cli/compare/v4.0.1...v4.0.2
+[v4.0.1]: https://github.com/SAP/ui5-cli/compare/v4.0.0...v4.0.1
+[v4.0.0]: https://github.com/SAP/ui5-cli/compare/v3.9.0...v4.0.0
+[v3.11.1]: https://github.com/SAP/ui5-cli/compare/v3.11.0...v3.11.1
+[v3.11.0]: https://github.com/SAP/ui5-cli/compare/v3.10.3...v3.11.0
+[v3.10.3]: https://github.com/SAP/ui5-cli/compare/v3.10.2...v3.10.3
+[v3.10.2]: https://github.com/SAP/ui5-cli/compare/v3.10.1...v3.10.2
+[v3.10.1]: https://github.com/SAP/ui5-cli/compare/v3.10.0...v3.10.1
+[v3.10.0]: https://github.com/SAP/ui5-cli/compare/v3.9.2...v3.10.0
+[v3.9.2]: https://github.com/SAP/ui5-cli/compare/v3.9.1...v3.9.2
+[v3.9.1]: https://github.com/SAP/ui5-cli/compare/v3.9.0...v3.9.1
+[v3.9.0]: https://github.com/SAP/ui5-cli/compare/v3.8.0...v3.9.0
+[v3.8.0]: https://github.com/SAP/ui5-cli/compare/v3.7.3...v3.8.0
+[v3.7.3]: https://github.com/SAP/ui5-cli/compare/v3.7.2...v3.7.3
+[v3.7.2]: https://github.com/SAP/ui5-cli/compare/v3.7.1...v3.7.2
+[v3.7.1]: https://github.com/SAP/ui5-cli/compare/v3.7.0...v3.7.1
+[v3.7.0]: https://github.com/SAP/ui5-cli/compare/v3.6.1...v3.7.0
+[v3.6.1]: https://github.com/SAP/ui5-cli/compare/v3.6.0...v3.6.1
+[v3.6.0]: https://github.com/SAP/ui5-cli/compare/v3.5.0...v3.6.0
+[v3.5.0]: https://github.com/SAP/ui5-cli/compare/v3.4.1...v3.5.0
+[v3.4.1]: https://github.com/SAP/ui5-cli/compare/v3.4.0...v3.4.1
+[v3.4.0]: https://github.com/SAP/ui5-cli/compare/v3.3.4...v3.4.0
+[v3.3.4]: https://github.com/SAP/ui5-cli/compare/v3.3.3...v3.3.4
+[v3.3.3]: https://github.com/SAP/ui5-cli/compare/v3.3.2...v3.3.3
+[v3.3.2]: https://github.com/SAP/ui5-cli/compare/v3.3.1...v3.3.2
+[v3.3.1]: https://github.com/SAP/ui5-cli/compare/v3.3.0...v3.3.1
+[v3.3.0]: https://github.com/SAP/ui5-cli/compare/v3.2.0...v3.3.0
+[v3.2.0]: https://github.com/SAP/ui5-cli/compare/v3.1.3...v3.2.0
+[v3.1.3]: https://github.com/SAP/ui5-cli/compare/v3.1.2...v3.1.3
+[v3.1.2]: https://github.com/SAP/ui5-cli/compare/v3.1.1...v3.1.2
+[v3.1.1]: https://github.com/SAP/ui5-cli/compare/v3.1.0...v3.1.1
+[v3.1.0]: https://github.com/SAP/ui5-cli/compare/v3.0.7...v3.1.0
+[v3.0.7]: https://github.com/SAP/ui5-cli/compare/v3.0.6...v3.0.7
+[v3.0.6]: https://github.com/SAP/ui5-cli/compare/v3.0.5...v3.0.6
+[v3.0.5]: https://github.com/SAP/ui5-cli/compare/v3.0.4...v3.0.5
+[v3.0.4]: https://github.com/SAP/ui5-cli/compare/v3.0.3...v3.0.4
+[v3.0.3]: https://github.com/SAP/ui5-cli/compare/v3.0.2...v3.0.3
+[v3.0.2]: https://github.com/SAP/ui5-cli/compare/v3.0.1...v3.0.2
+[v3.0.1]: https://github.com/SAP/ui5-cli/compare/v3.0.0...v3.0.1
+[v3.0.0]: https://github.com/SAP/ui5-cli/compare/v2.14.1...v3.0.0
+[v2.14.17]: https://github.com/SAP/ui5-cli/compare/v2.14.16...v2.14.17
+[v2.14.16]: https://github.com/SAP/ui5-cli/compare/v2.14.15...v2.14.16
+[v2.14.15]: https://github.com/SAP/ui5-cli/compare/v2.14.14...v2.14.15
+[v2.14.14]: https://github.com/SAP/ui5-cli/compare/v2.14.13...v2.14.14
+[v2.14.13]: https://github.com/SAP/ui5-cli/compare/v2.14.12...v2.14.13
+[v2.14.12]: https://github.com/SAP/ui5-cli/compare/v2.14.11...v2.14.12
+[v2.14.11]: https://github.com/SAP/ui5-cli/compare/v2.14.10...v2.14.11
+[v2.14.10]: https://github.com/SAP/ui5-cli/compare/v2.14.9...v2.14.10
+[v2.14.9]: https://github.com/SAP/ui5-cli/compare/v2.14.8...v2.14.9
+[v2.14.8]: https://github.com/SAP/ui5-cli/compare/v2.14.7...v2.14.8
+[v2.14.7]: https://github.com/SAP/ui5-cli/compare/v2.14.6...v2.14.7
+[v2.14.6]: https://github.com/SAP/ui5-cli/compare/v2.14.5...v2.14.6
+[v2.14.5]: https://github.com/SAP/ui5-cli/compare/v2.14.4...v2.14.5
+[v2.14.4]: https://github.com/SAP/ui5-cli/compare/v2.14.3...v2.14.4
+[v2.14.3]: https://github.com/SAP/ui5-cli/compare/v2.14.2...v2.14.3
+[v2.14.2]: https://github.com/SAP/ui5-cli/compare/v2.14.1...v2.14.2
+[v2.14.1]: https://github.com/SAP/ui5-cli/compare/v2.14.0...v2.14.1
+[v2.14.0]: https://github.com/SAP/ui5-cli/compare/v2.13.0...v2.14.0
+[v2.13.0]: https://github.com/SAP/ui5-cli/compare/v2.12.1...v2.13.0
+[v2.12.1]: https://github.com/SAP/ui5-cli/compare/v2.12.0...v2.12.1
+[v2.12.0]: https://github.com/SAP/ui5-cli/compare/v2.11.3...v2.12.0
+[v2.11.3]: https://github.com/SAP/ui5-cli/compare/v2.11.2...v2.11.3
+[v2.11.2]: https://github.com/SAP/ui5-cli/compare/v2.11.1...v2.11.2
+[v2.11.1]: https://github.com/SAP/ui5-cli/compare/v2.11.0...v2.11.1
+[v2.11.0]: https://github.com/SAP/ui5-cli/compare/v2.10.4...v2.11.0
+[v2.10.4]: https://github.com/SAP/ui5-cli/compare/v2.10.3...v2.10.4
+[v2.10.3]: https://github.com/SAP/ui5-cli/compare/v2.10.2...v2.10.3
+[v2.10.2]: https://github.com/SAP/ui5-cli/compare/v2.10.1...v2.10.2
+[v2.10.1]: https://github.com/SAP/ui5-cli/compare/v2.10.0...v2.10.1
+[v2.10.0]: https://github.com/SAP/ui5-cli/compare/v2.9.3...v2.10.0
+[v2.9.3]: https://github.com/SAP/ui5-cli/compare/v2.9.2...v2.9.3
+[v2.9.2]: https://github.com/SAP/ui5-cli/compare/v2.9.1...v2.9.2
+[v2.9.1]: https://github.com/SAP/ui5-cli/compare/v2.9.0...v2.9.1
+[v2.9.0]: https://github.com/SAP/ui5-cli/compare/v2.8.1...v2.9.0
+[v2.8.1]: https://github.com/SAP/ui5-cli/compare/v2.8.0...v2.8.1
+[v2.8.0]: https://github.com/SAP/ui5-cli/compare/v2.7.1...v2.8.0
+[v2.7.1]: https://github.com/SAP/ui5-cli/compare/v2.7.0...v2.7.1
+[v2.7.0]: https://github.com/SAP/ui5-cli/compare/v2.6.6...v2.7.0
+[v2.6.6]: https://github.com/SAP/ui5-cli/compare/v2.6.5...v2.6.6
+[v2.6.5]: https://github.com/SAP/ui5-cli/compare/v2.6.4...v2.6.5
+[v2.6.4]: https://github.com/SAP/ui5-cli/compare/v2.6.3...v2.6.4
+[v2.6.3]: https://github.com/SAP/ui5-cli/compare/v2.6.2...v2.6.3
+[v2.6.2]: https://github.com/SAP/ui5-cli/compare/v2.6.1...v2.6.2
+[v2.6.1]: https://github.com/SAP/ui5-cli/compare/v2.6.0...v2.6.1
+[v2.6.0]: https://github.com/SAP/ui5-cli/compare/v2.5.0...v2.6.0
+[v2.5.0]: https://github.com/SAP/ui5-cli/compare/v2.4.5...v2.5.0
+[v2.4.5]: https://github.com/SAP/ui5-cli/compare/v2.4.4...v2.4.5
+[v2.4.4]: https://github.com/SAP/ui5-cli/compare/v2.4.3...v2.4.4
+[v2.4.3]: https://github.com/SAP/ui5-cli/compare/v2.4.2...v2.4.3
+[v2.4.2]: https://github.com/SAP/ui5-cli/compare/v2.4.1...v2.4.2
+[v2.4.1]: https://github.com/SAP/ui5-cli/compare/v2.4.0...v2.4.1
+[v2.4.0]: https://github.com/SAP/ui5-cli/compare/v2.3.2...v2.4.0
+[v2.3.2]: https://github.com/SAP/ui5-cli/compare/v2.3.1...v2.3.2
+[v2.3.1]: https://github.com/SAP/ui5-cli/compare/v2.3.0...v2.3.1
+[v2.3.0]: https://github.com/SAP/ui5-cli/compare/v2.2.6...v2.3.0
+[v2.2.6]: https://github.com/SAP/ui5-cli/compare/v2.2.5...v2.2.6
+[v2.2.5]: https://github.com/SAP/ui5-cli/compare/v2.2.4...v2.2.5
+[v2.2.4]: https://github.com/SAP/ui5-cli/compare/v2.2.3...v2.2.4
+[v2.2.3]: https://github.com/SAP/ui5-cli/compare/v2.2.2...v2.2.3
+[v2.2.2]: https://github.com/SAP/ui5-cli/compare/v2.2.1...v2.2.2
+[v2.2.1]: https://github.com/SAP/ui5-cli/compare/v2.2.0...v2.2.1
+[v2.2.0]: https://github.com/SAP/ui5-cli/compare/v2.1.0...v2.2.0
+[v2.1.0]: https://github.com/SAP/ui5-cli/compare/v2.0.3...v2.1.0
+[v2.0.3]: https://github.com/SAP/ui5-cli/compare/v2.0.2...v2.0.3
+[v2.0.2]: https://github.com/SAP/ui5-cli/compare/v2.0.1...v2.0.2
+[v2.0.1]: https://github.com/SAP/ui5-cli/compare/v2.0.0...v2.0.1
+[v2.0.0]: https://github.com/SAP/ui5-cli/compare/v1.14.0...v2.0.0
+[v1.14.0]: https://github.com/SAP/ui5-cli/compare/v1.13.1...v1.14.0
+[v1.13.1]: https://github.com/SAP/ui5-cli/compare/v1.13.0...v1.13.1
+[v1.13.0]: https://github.com/SAP/ui5-cli/compare/v1.12.2...v1.13.0
+[v1.12.2]: https://github.com/SAP/ui5-cli/compare/v1.12.1...v1.12.2
+[v1.12.1]: https://github.com/SAP/ui5-cli/compare/v1.12.0...v1.12.1
+[v1.12.0]: https://github.com/SAP/ui5-cli/compare/v1.11.1...v1.12.0
+[v1.11.1]: https://github.com/SAP/ui5-cli/compare/v1.11.0...v1.11.1
+[v1.11.0]: https://github.com/SAP/ui5-cli/compare/v1.10.0...v1.11.0
+[v1.10.0]: https://github.com/SAP/ui5-cli/compare/v1.9.0...v1.10.0
+[v1.9.0]: https://github.com/SAP/ui5-cli/compare/v1.8.1...v1.9.0
+[v1.8.1]: https://github.com/SAP/ui5-cli/compare/v1.8.0...v1.8.1
+[v1.8.0]: https://github.com/SAP/ui5-cli/compare/v1.7.0...v1.8.0
+[v1.7.0]: https://github.com/SAP/ui5-cli/compare/v1.6.0...v1.7.0
+[v1.6.0]: https://github.com/SAP/ui5-cli/compare/v1.5.5...v1.6.0
+[v1.5.5]: https://github.com/SAP/ui5-cli/compare/v1.5.4...v1.5.5
+[v1.5.4]: https://github.com/SAP/ui5-cli/compare/v1.5.3...v1.5.4
+[v1.5.3]: https://github.com/SAP/ui5-cli/compare/v1.5.2...v1.5.3
+[v1.5.2]: https://github.com/SAP/ui5-cli/compare/v1.5.1...v1.5.2
+[v1.5.1]: https://github.com/SAP/ui5-cli/compare/v1.5.0...v1.5.1
+[v1.5.0]: https://github.com/SAP/ui5-cli/compare/v1.4.4...v1.5.0
+[v1.4.4]: https://github.com/SAP/ui5-cli/compare/v1.4.3...v1.4.4
+[v1.4.3]: https://github.com/SAP/ui5-cli/compare/v1.4.2...v1.4.3
+[v1.4.2]: https://github.com/SAP/ui5-cli/compare/v1.4.1...v1.4.2
+[v1.4.1]: https://github.com/SAP/ui5-cli/compare/v1.4.0...v1.4.1
+[v1.4.0]: https://github.com/SAP/ui5-cli/compare/v1.3.1...v1.4.0
+[v1.3.1]: https://github.com/SAP/ui5-cli/compare/v1.3.0...v1.3.1
+[v1.3.0]: https://github.com/SAP/ui5-cli/compare/v1.2.4...v1.3.0
+[v1.2.4]: https://github.com/SAP/ui5-cli/compare/v1.2.3...v1.2.4
+[v1.2.3]: https://github.com/SAP/ui5-cli/compare/v1.2.2...v1.2.3
+[v1.2.2]: https://github.com/SAP/ui5-cli/compare/v1.2.1...v1.2.2
+[v1.2.1]: https://github.com/SAP/ui5-cli/compare/v1.2.0...v1.2.1
+[v1.2.0]: https://github.com/SAP/ui5-cli/compare/v1.1.0...v1.2.0
+[v1.1.0]: https://github.com/SAP/ui5-cli/compare/v1.0.1...v1.1.0
+[v1.0.1]: https://github.com/SAP/ui5-cli/compare/v1.0.0...v1.0.1
+[v1.0.0]: https://github.com/SAP/ui5-cli/compare/v0.2.9...v1.0.0
+[v0.2.9]: https://github.com/SAP/ui5-cli/compare/v0.2.8...v0.2.9
+[v0.2.8]: https://github.com/SAP/ui5-cli/compare/v0.2.7...v0.2.8
+[v0.2.7]: https://github.com/SAP/ui5-cli/compare/v0.2.6...v0.2.7
+[v0.2.6]: https://github.com/SAP/ui5-cli/compare/v0.2.5...v0.2.6
+[v0.2.5]: https://github.com/SAP/ui5-cli/compare/v0.2.4...v0.2.5
+[v0.2.4]: https://github.com/SAP/ui5-cli/compare/v0.2.3...v0.2.4
+[v0.2.3]: https://github.com/SAP/ui5-cli/compare/v0.2.2...v0.2.3
+[v0.2.2]: https://github.com/SAP/ui5-cli/compare/v0.2.1...v0.2.2
+[v0.2.1]: https://github.com/SAP/ui5-cli/compare/v0.2.0...v0.2.1
+[v0.2.0]: https://github.com/SAP/ui5-cli/compare/v0.1.0...v0.2.0
+[v0.1.0]: https://github.com/SAP/ui5-cli/compare/v0.0.2...v0.1.0
+[v0.0.2]: https://github.com/SAP/ui5-cli/compare/v0.0.1...v0.0.2
diff --git a/packages/cli/CONTRIBUTING.md b/packages/cli/CONTRIBUTING.md
new file mode 100644
index 00000000000..2ddb6276ed5
--- /dev/null
+++ b/packages/cli/CONTRIBUTING.md
@@ -0,0 +1,3 @@
+# Contributing to the UI5 CLI
+
+See CONTRIBUTING.md in the [UI5/cli](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md) repository.
diff --git a/packages/cli/LICENSE.txt b/packages/cli/LICENSE.txt
new file mode 100644
index 00000000000..261eeb9e9f8
--- /dev/null
+++ b/packages/cli/LICENSE.txt
@@ -0,0 +1,201 @@
+ 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/packages/cli/LICENSES/Apache-2.0.txt b/packages/cli/LICENSES/Apache-2.0.txt
new file mode 100644
index 00000000000..4ed90b95224
--- /dev/null
+++ b/packages/cli/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/packages/cli/README.md b/packages/cli/README.md
new file mode 100644
index 00000000000..0c3ee689f7c
--- /dev/null
+++ b/packages/cli/README.md
@@ -0,0 +1,28 @@
+
+
+# ui5-cli
+> `ui5` Command Line Interface
+> Part of the [UI5 CLI](https://github.com/UI5/cli)
+
+[](https://api.reuse.software/info/github.com/SAP/ui5-cli)
+[](https://dev.azure.com/sap/opensource/_build/latest?definitionId=33&branchName=v4)
+[](https://www.npmjs.com/package/@ui5/cli)
+[](https://coveralls.io/github/SAP/ui5-cli)
+
+## Documentation
+UI5 CLI documentation can be found here: [ui5.github.io/cli](https://ui5.github.io/cli/pages/CLI/)
+
+## Contributing
+
+Please check our [Contribution Guidelines](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md).
+
+## Support
+
+Please follow our [Contribution Guidelines](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md#report-an-issue) on how to report an issue.
+
+Please report issues in the main [UI5 CLI](https://github.com/UI5/cli) repository.
+
+## Release History
+
+See [CHANGELOG.md](CHANGELOG.md).
+A consolidated changelog (including changes from the other UI5 CLI modules) is available on the [Releases tab](https://github.com/SAP/ui5-cli/releases).
diff --git a/packages/cli/REUSE.toml b/packages/cli/REUSE.toml
new file mode 100644
index 00000000000..5ee988b44fd
--- /dev/null
+++ b/packages/cli/REUSE.toml
@@ -0,0 +1,11 @@
+version = 1
+SPDX-PackageName = "ui5-cli"
+SPDX-PackageSupplier = "SAP OpenUI5 "
+SPDX-PackageDownloadLocation = "https://github.com/SAP/ui5-cli"
+SPDX-PackageComment = "The code in this project may include calls to APIs (“API Calls”) of\n SAP or third-party products or services developed outside of this project\n (“External Products”).\n “APIs” means application programming interfaces, as well as their respective\n specifications and implementing code that allows software to communicate with\n other software.\n API Calls to External Products are not licensed under the open source license\n that governs this project. The use of such API Calls and related External\n Products are subject to applicable additional agreements with the relevant\n provider of the External Products. In no event shall the open source license\n that governs this project grant any rights in or to any External Products,or\n alter, expand or supersede any terms of the applicable additional agreements.\n If you have a valid license agreement with SAP for the use of a particular SAP\n External Product, then you may make use of any API Calls included in this\n project’s code for that SAP External Product, subject to the terms of such\n license agreement. If you do not have a valid license agreement for the use of\n a particular SAP External Product, then you may only make use of any API Calls\n in this project for that SAP External Product for your internal, non-productive\n and non-commercial test and evaluation of such API Calls. Nothing herein grants\n you any rights to use or access any SAP External Product, or provide any third\n parties the right to use of access any SAP External Product, through API Calls."
+
+[[annotations]]
+path = "**"
+precedence = "aggregate"
+SPDX-FileCopyrightText = "2025 SAP SE or an SAP affiliate company and UI5 CLI contributors"
+SPDX-License-Identifier = "Apache-2.0"
diff --git a/packages/cli/azure-pipelines.yml b/packages/cli/azure-pipelines.yml
new file mode 100644
index 00000000000..929b3342876
--- /dev/null
+++ b/packages/cli/azure-pipelines.yml
@@ -0,0 +1,81 @@
+# Node.js
+# Build a general Node.js project with npm.
+# Add steps that analyze code, save build artifacts, deploy, and more:
+# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
+
+trigger:
+- v4
+
+variables:
+ CI: true
+
+strategy:
+ matrix:
+ linux_node_lts_20_min_version:
+ imageName: 'ubuntu-24.04'
+ node_version: 20.11.0
+ linux_node_22_min_version:
+ imageName: 'ubuntu-24.04'
+ node_version: 22.1.0
+ linux_node_lts_20:
+ imageName: 'ubuntu-24.04'
+ node_version: 20.x
+ mac_node_lts_20:
+ imageName: 'macos-13'
+ node_version: 20.x
+ windows_node_lts_20:
+ imageName: 'windows-2022'
+ node_version: 20.x
+ linux_node_22:
+ imageName: 'ubuntu-24.04'
+ node_version: 22.x
+ mac_node_22:
+ imageName: 'macos-13'
+ node_version: 22.x
+ windows_node_22:
+ imageName: 'windows-2022'
+ node_version: 22.x
+ linux_node_24:
+ imageName: 'ubuntu-24.04'
+ node_version: 24.x
+ mac_node_24:
+ imageName: 'macos-13'
+ node_version: 24.x
+ windows_node_24:
+ imageName: 'windows-2022'
+ node_version: 24.x
+
+pool:
+ vmImage: $(imageName)
+
+steps:
+- task: NodeTool@0
+ inputs:
+ versionSpec: $(node_version)
+ displayName: Install Node.js
+
+- script: npm ci
+ displayName: Install Dependencies
+
+- script: npm ls --prod
+ 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@2
+ displayName: Publish Test Coverage Results
+ condition: succeededOrFailed()
+ inputs:
+ summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml'
+
+- script: npm run coverage
+ displayName: Run Test Natively in Case of Failures
+ condition: failed()
diff --git a/packages/cli/bin/ui5.cjs b/packages/cli/bin/ui5.cjs
new file mode 100755
index 00000000000..7fd57f86933
--- /dev/null
+++ b/packages/cli/bin/ui5.cjs
@@ -0,0 +1,123 @@
+#!/usr/bin/env node
+
+// NOTE: This file should be compatible to as many Node.js versions as possible
+// so that the message for unsupported Node.js versions can be displayed.
+
+const path = require("path");
+
+const ui5 = {
+
+ getPackageJson() {
+ return require("../package.json");
+ },
+
+ checkRequirements({pkg, nodeVersion}) {
+ let semver;
+ try {
+ semver = require("semver");
+ } catch (err) {
+ // SyntaxError indicates an outdated Node.js version
+ if (err.name !== "SyntaxError") {
+ throw err;
+ }
+ }
+ if (
+ pkg.engines && pkg.engines.node &&
+ (!semver || !semver.satisfies(nodeVersion, pkg.engines.node, {includePrerelease: true}))
+ ) {
+ process.stderr.write("==================== UNSUPPORTED NODE.JS VERSION ====================");
+ process.stderr.write("\n");
+ process.stderr.write("You are using an unsupported version of Node.js");
+ process.stderr.write("\n");
+ process.stderr.write("Detected version " + nodeVersion +
+ " but " + pkg.name + " requires " + pkg.engines.node);
+ process.stderr.write("\n\n");
+ process.stderr.write("=> Please upgrade to a supported version of Node.js to use this tool");
+ process.stderr.write("\n");
+ process.stderr.write("=====================================================================");
+ process.stderr.write("\n");
+ return false;
+ }
+
+ if (semver && semver.prerelease(nodeVersion)) {
+ process.stderr.write("====================== UNSTABLE NODE.JS VERSION =====================");
+ process.stderr.write("\n");
+ process.stderr.write("You are using an unstable version of Node.js");
+ process.stderr.write("\n");
+ process.stderr.write("Detected Node.js version " + nodeVersion);
+ process.stderr.write("\n\n");
+ process.stderr.write("=> Please note that an unstable version might cause unexpected");
+ process.stderr.write("\n");
+ process.stderr.write(" behavior. For productive use please consider using a stable");
+ process.stderr.write("\n");
+ process.stderr.write(" version of Node.js! For the release policy of Node.js, see");
+ process.stderr.write("\n");
+ process.stderr.write(" https://nodejs.org/en/about/releases");
+ process.stderr.write("\n");
+ process.stderr.write("=====================================================================");
+ process.stderr.write("\n");
+ }
+
+ return true;
+ },
+
+ async invokeLocalInstallation(pkg) {
+ if (process.env.UI5_CLI_NO_LOCAL) {
+ return false;
+ }
+ // Prefer a local installation of @ui5/cli.
+ // This will invoke the local CLI, so no further action required
+ const {default: importLocal} = await import("import-local");
+ let ui5Local = importLocal(path.join(__dirname, "ui5.cjs"));
+ if (!ui5Local) {
+ // Fallback to ui5.js (CLI version < v3)
+ // NOTE: Entries within package.json "exports" are not respected on Windows,
+ // so only checking for ui5.js does not work.
+ ui5Local = importLocal(path.join(__dirname, "ui5.js"));
+ }
+ if (!ui5Local || ui5Local === module.exports) {
+ // Either no local installation found or this script is the local installation
+ // (invocation within ui5-cli repo)
+ return false;
+ }
+ if (process.argv.includes("--verbose")) {
+ process.stderr.write(`INFO: This project contains an individual ${pkg.name} installation which ` +
+ "will be used over the global one.");
+ process.stderr.write("\n");
+ process.stderr.write("See https://github.com/SAP/ui5-cli#local-vs-global-installation for details.");
+ process.stderr.write("\n\n");
+ } else {
+ process.stdout.write(`INFO: Using local ${pkg.name} installation`);
+ process.stdout.write("\n\n");
+ }
+ return true;
+ },
+
+ async invokeCLI(pkg) {
+ const {default: cli} = await import("../lib/cli/cli.js");
+ await cli(pkg);
+ },
+
+ async main() {
+ const pkg = ui5.getPackageJson();
+ if (!ui5.checkRequirements({pkg, nodeVersion: process.version})) {
+ process.exit(1);
+ } else {
+ const localInstallationInvoked = await ui5.invokeLocalInstallation(pkg);
+ if (!localInstallationInvoked) {
+ await ui5.invokeCLI(pkg);
+ }
+ }
+ }
+};
+
+module.exports = ui5;
+
+if (process.env.NODE_ENV !== "test" || process.env.UI5_CLI_TEST_BIN_RUN_MAIN !== "false") {
+ ui5.main().catch((err) => {
+ process.stderr.write("Fatal Error: Unable to initialize UI5 CLI");
+ process.stderr.write("\n");
+ process.stderr.write(err);
+ process.exit(1);
+ });
+}
diff --git a/packages/cli/eslint.common.config.js b/packages/cli/eslint.common.config.js
new file mode 100644
index 00000000000..07876d526f0
--- /dev/null
+++ b/packages/cli/eslint.common.config.js
@@ -0,0 +1,99 @@
+import jsdoc from "eslint-plugin-jsdoc";
+import ava from "eslint-plugin-ava";
+import globals from "globals";
+import js from "@eslint/js";
+import google from "eslint-config-google";
+
+export default [{
+ ignores: [ // Common ignore patterns across all tooling repos
+ "**/coverage/",
+ "test/tmp/",
+ "test/expected/",
+ "test/fixtures/",
+ "**/docs/",
+ "**/jsdocs/",
+ ],
+}, js.configs.recommended, google, ava.configs["flat/recommended"], {
+ name: "Common ESLint config used for all tooling repos",
+
+ plugins: {
+ jsdoc,
+ },
+
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ },
+
+ ecmaVersion: 2023,
+ sourceType: "module",
+ },
+
+ settings: {
+ jsdoc: {
+ mode: "jsdoc",
+
+ tagNamePreference: {
+ return: "returns",
+ augments: "extends",
+ },
+ },
+ },
+
+ 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",
+ "no-console": 2, // Disallow console.log()
+ "no-eval": 2,
+ // The following rule must be disabled as of ESLint 9.
+ // It's removed and causes issues when present
+ // https://eslint.org/docs/latest/rules/valid-jsdoc
+ "valid-jsdoc": 0,
+ "jsdoc/check-examples": 0,
+ "jsdoc/check-param-names": 2,
+ "jsdoc/check-tag-names": 2,
+ "jsdoc/check-types": 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/tag-lines": [2, "any", {
+ startLines: 1,
+ }],
+
+ "jsdoc/valid-types": 0,
+ "ava/assertion-arguments": 0,
+ },
+}
+];
diff --git a/packages/cli/eslint.config.js b/packages/cli/eslint.config.js
new file mode 100644
index 00000000000..c91551a2321
--- /dev/null
+++ b/packages/cli/eslint.config.js
@@ -0,0 +1,14 @@
+import eslintCommonConfig from "./eslint.common.config.js";
+
+export default [
+ ...eslintCommonConfig, // Load common ESLint config
+ {
+ files: ["bin/ui5.cjs"],
+
+ languageOptions: {
+ globals: {},
+ ecmaVersion: 2020,
+ sourceType: "commonjs",
+ },
+ },
+];
diff --git a/packages/cli/jsdoc-plugin.cjs b/packages/cli/jsdoc-plugin.cjs
new file mode 100644
index 00000000000..cd7ef446d0f
--- /dev/null
+++ b/packages/cli/jsdoc-plugin.cjs
@@ -0,0 +1,9 @@
+/*
+ * This plugin fixes unexpected JSDoc behavior that prevents us from using types that start with an at-sign (@).
+ * JSDoc doesn't see "{@" as a valid type expression, probably as there's also {@link ...}.
+ */
+exports.handlers = {
+ jsdocCommentFound: function(e) {
+ e.comment = e.comment.replace(/{@ui5\//g, "{ @ui5/");
+ }
+};
diff --git a/packages/cli/jsdoc.json b/packages/cli/jsdoc.json
new file mode 100644
index 00000000000..d9d94ebae4e
--- /dev/null
+++ b/packages/cli/jsdoc.json
@@ -0,0 +1,62 @@
+{
+ "tags": {
+ "allowUnknownTags": false
+ },
+ "source": {
+ "include": ["README.md"],
+ "includePattern": ".+\\.js$",
+ "excludePattern": "(node_modules(\\\\|/))"
+ },
+ "plugins": [
+ "jsdoc-plugin.cjs"
+ ],
+ "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 CLI - API Reference",
+ "type": "website",
+ "image": "https://ui5.github.io/cli/v4/images/UI5_logo_wide.png",
+ "site_name": "UI5 CLI - API Reference",
+ "url": "https://ui5.github.io/cli/"
+ },
+ "docdash": {
+ "sectionOrder": [
+ "Modules",
+ "Namespaces",
+ "Classes",
+ "Externals",
+ "Events",
+ "Mixins",
+ "Tutorials",
+ "Interfaces"
+ ],
+ "meta": {
+ "title": "UI5 CLI - API Reference - UI5 CLI",
+ "description": "UI5 CLI - API Reference - UI5 CLI",
+ "keyword": "openui5 sapui5 ui5 build development tool api reference"
+ },
+ "search": true,
+ "wrap": true,
+ "menu": {
+ "GitHub": {
+ "href": "https://github.com/SAP/ui5-cli",
+ "target": "_blank",
+ "class": "menu-item",
+ "id": "github_link"
+ }
+ }
+ }
+}
diff --git a/packages/cli/lib/cli/base.js b/packages/cli/lib/cli/base.js
new file mode 100644
index 00000000000..260dd1d36b4
--- /dev/null
+++ b/packages/cli/lib/cli/base.js
@@ -0,0 +1,141 @@
+import chalk from "chalk";
+import {isLogLevelEnabled} from "@ui5/logger";
+import ConsoleWriter from "@ui5/logger/writers/Console";
+
+export default function(cli) {
+ cli.usage("Usage: ui5 [options]")
+ .demandCommand(1, "Command required")
+ .option("config", {
+ alias: "c",
+ describe: "Path to project configuration file in YAML format",
+ type: "string"
+ })
+ .option("dependency-definition", {
+ describe: "Path to a YAML file containing the project's dependency tree. " +
+ "This option will disable resolution of node package dependencies.",
+ type: "string"
+ })
+ .option("workspace-config", {
+ describe: "Path to workspace configuration file in YAML format",
+ type: "string"
+ })
+ .option("workspace", {
+ alias: "w",
+ describe: "Name of the workspace configuration to use",
+ default: "default",
+ type: "string"
+ })
+ .option("loglevel", {
+ alias: "log-level",
+ describe: "Set the logging level",
+ default: "info",
+ type: "string",
+ choices: ["silent", "error", "warn", "info", "perf", "verbose", "silly"]
+ })
+ .option("verbose", {
+ describe: "Enable verbose logging.",
+ default: false,
+ type: "boolean"
+ })
+ .option("perf", {
+ describe: "Enable performance measurements and related logging.",
+ default: false,
+ type: "boolean"
+ })
+ .option("silent", {
+ describe: "Disable all log output.",
+ default: false,
+ type: "boolean"
+ })
+ .coerce([
+ // base.js
+ "config", "dependency-definition", "workspace-config", "workspace", "log-level",
+
+ // tree.js, build.js & serve.js
+ "framework-version", "cache-mode",
+
+ // build.js
+ "dest",
+
+ // serve.js
+ "open", "port", "key", "cert",
+ ], (arg) => {
+ // If an option is specified multiple times, yargs creates an array for all the values,
+ // independently of whether the option is of type "array" or "string".
+ // This is unexpected for options listed above, which should all only have only one definitive value.
+ // The yargs behavior could be disabled by using the parserConfiguration "duplicate-arguments-array": true
+ // However, yargs would then cease to create arrays for those options where we *do* expect the
+ // automatic creation of arrays in case the option is specified multiple times. Like "--include-task".
+ // Also see https://github.com/yargs/yargs/issues/1318
+ // Note: This is not necessary for options of type "boolean"
+ if (Array.isArray(arg)) {
+ // If the option is specified multiple times, use the value of the last option
+ return arg[arg.length - 1];
+ }
+ return arg;
+ })
+ .showHelpOnFail(true)
+ .strict(true)
+ .alias("help", "h")
+ .alias("version", "v")
+ .example("ui5 --dependency-definition /path/to/projectDependencies.yaml",
+ "Execute command using a static dependency tree instead of resolving node package dependencies")
+ .example("ui5 --config /path/to/ui5.yaml",
+ "Execute command using a project configuration from custom path")
+ .example("ui5 --workspace dolphin",
+ "Execute command using the 'dolphin' workspace of a ui5-workspace.yaml")
+ .example("ui5 --log-level silly",
+ "Execute command with the maximum log output")
+ .fail(function(msg, err, yargs) {
+ if (err) {
+ ConsoleWriter.stop();
+ // Exception
+ if (isLogLevelEnabled("error")) {
+ process.stderr.write("\n");
+ process.stderr.write(chalk.bold.red("⚠️ Process Failed With Error"));
+
+ process.stderr.write("\n\n");
+ process.stderr.write(chalk.underline("Error Message:"));
+ process.stderr.write("\n");
+ process.stderr.write(err.message);
+ process.stderr.write("\n");
+
+ // Unexpected errors should always be logged with stack trace
+ const unexpectedErrors = ["SyntaxError", "ReferenceError", "TypeError"];
+ if (unexpectedErrors.includes(err.name) || isLogLevelEnabled("verbose")) {
+ process.stderr.write("\n\n");
+ process.stderr.write(chalk.underline("Stack Trace:"));
+ process.stderr.write("\n");
+ process.stderr.write(err.stack);
+ process.stderr.write("\n");
+ if (err.cause instanceof Error && err.cause.stack) {
+ process.stderr.write(chalk.underline("Error Cause Stack Trace:\n"));
+ process.stderr.write(err.cause.stack + "\n");
+ process.stderr.write("\n");
+ }
+ process.stderr.write(
+ chalk.dim(
+ `If you think this is an issue of the UI5 CLI, you might report it using the ` +
+ `following URL: `) +
+ chalk.dim.bold.underline(`https://github.com/UI5/cli/issues/new/choose`));
+ process.stderr.write("\n");
+ } else {
+ process.stderr.write("\n\n");
+ process.stderr.write(chalk.dim(
+ `For details, execute the same command again with an additional '--verbose' parameter`));
+ process.stderr.write("\n");
+ }
+ }
+ } else {
+ // Yargs error
+ process.stderr.write(chalk.bold.yellow("Command Failed:"));
+ process.stderr.write("\n");
+ process.stderr.write(`${msg}`);
+ process.stderr.write("\n\n");
+ process.stderr.write(chalk.dim(`See 'ui5 --help'`));
+ process.stderr.write("\n");
+ }
+ process.exit(1);
+ });
+}
+
diff --git a/packages/cli/lib/cli/cli.js b/packages/cli/lib/cli/cli.js
new file mode 100644
index 00000000000..e46a519368c
--- /dev/null
+++ b/packages/cli/lib/cli/cli.js
@@ -0,0 +1,74 @@
+import yargs from "yargs";
+import {hideBin} from "yargs/helpers";
+import {setVersion} from "./version.js";
+import base from "./base.js";
+import {fileURLToPath} from "node:url";
+import {readdir} from "node:fs/promises";
+
+async function getCommands() {
+ return (await readdir(new URL("./commands", import.meta.url), {withFileTypes: true}))
+ .filter((e) => !e.isDirectory() && e.name.endsWith(".js"))
+ .map((e) => new URL(`./commands/${e.name}`, import.meta.url));
+}
+
+export default async (pkg) => {
+ // Only import update-notifier when it's not disabled
+ // See https://github.com/yeoman/update-notifier/blob/3046d0f61a57f8270291b6ab271f8a12df8421a6/update-notifier.js#L57-L60
+ // The "is-ci" check is not executed, but will be checked by update-notifier itself then
+ const NO_UPDATE_NOTIFIER = "--no-update-notifier";
+ const disableUpdateNotifier =
+ "NO_UPDATE_NOTIFIER" in process.env ||
+ process.env.NODE_ENV === "test" ||
+ process.argv.includes(NO_UPDATE_NOTIFIER);
+
+ if (!disableUpdateNotifier) {
+ const {default: updateNotifier} = await import("update-notifier");
+ updateNotifier({
+ pkg,
+ updateCheckInterval: 86400000, // 1 day
+ shouldNotifyInNpmScript: true
+ }).notify();
+ }
+
+ // Remove --no-update-notifier from argv as it's not known to yargs, but we still want to support using it
+ if (process.argv.includes(NO_UPDATE_NOTIFIER)) {
+ process.argv = process.argv.filter((v) => v !== NO_UPDATE_NOTIFIER);
+ }
+
+ const cli = yargs(hideBin(process.argv));
+ cli.parserConfiguration({
+ "parse-numbers": false
+ });
+
+ // Explicitly set CLI version as the yargs default might
+ // be wrong in case a local CLI installation is used
+ // Also add CLI location
+ const ui5JsPath = fileURLToPath(new URL("../../bin/ui5.cjs", import.meta.url));
+ const pkgVersion = `${pkg.version} (from ${ui5JsPath})`;
+
+ setVersion(pkgVersion);
+ cli.version(pkgVersion);
+
+ // Explicitly set script name to prevent windows from displaying "ui5.js"
+ cli.scriptName("ui5");
+
+ // Setup general options and error handling
+ base(cli);
+
+ // CLI modules
+ // YError: loading a directory of commands is not supported yet for ESM
+ // cli.commandDir("../lib/cli/commands");
+ // See https://github.com/yargs/yargs/issues/2152
+ const commandModules = await getCommands();
+ for (const modulePath of commandModules) {
+ const {default: command} = await import(modulePath);
+ cli.command(command);
+ }
+
+ // Format terminal output to full available width
+ cli.wrap(cli.terminalWidth());
+
+ // yargs registers a get method on the argv property.
+ // The property needs to be accessed to initialize everything.
+ cli.argv;
+};
diff --git a/packages/cli/lib/cli/commands/add.js b/packages/cli/lib/cli/commands/add.js
new file mode 100644
index 00000000000..d8943a6067c
--- /dev/null
+++ b/packages/cli/lib/cli/commands/add.js
@@ -0,0 +1,92 @@
+// Add
+import base from "../middlewares/base.js";
+const addCommand = {
+ command: "add [--development] [--optional] ",
+ describe: "Add SAPUI5/OpenUI5 framework libraries to the project configuration.",
+ middlewares: [base]
+};
+
+addCommand.builder = function(cli) {
+ return cli
+ .positional("framework-libraries", {
+ describe: "Framework library names",
+ type: "string"
+ }).option("development", {
+ describe: "Add as development dependency",
+ alias: ["D", "dev"],
+ default: false,
+ type: "boolean"
+ }).option("optional", {
+ describe: "Add as optional dependency",
+ alias: ["O"],
+ default: false,
+ type: "boolean"
+ })
+ .example("$0 add sap.ui.core sap.m", "Add the framework libraries sap.ui.core and sap.m as dependencies")
+ .example("$0 add -D sap.ui.support", "Add the framework library sap.ui.support as development dependency")
+ .example("$0 add --optional themelib_sap_fiori_3",
+ "Add the framework library themelib_sap_fiori_3 as optional dependency");
+};
+
+addCommand.handler = async function(argv) {
+ const libraryNames = argv["framework-libraries"] || [];
+ const development = argv["development"];
+ const optional = argv["optional"];
+
+ if (libraryNames.length === 0) {
+ // Should not happen via yargs as parameter is mandatory
+ throw new Error("Missing mandatory parameter framework-libraries");
+ }
+
+ if (development && optional) {
+ throw new Error("Options 'development' and 'optional' cannot be combined");
+ }
+
+ const projectGraphOptions = {
+ dependencyDefinition: argv.dependencyDefinition,
+ config: argv.config
+ };
+
+ const libraries = libraryNames.map((name) => {
+ const library = {name};
+ if (optional) {
+ library.optional = true;
+ } else if (development) {
+ library.development = true;
+ }
+ return library;
+ });
+
+ const {default: add} = await import("../../framework/add.js");
+ const {yamlUpdated} = await add({
+ projectGraphOptions,
+ libraries
+ });
+
+ const library = libraries.length === 1 ? "library": "libraries";
+ if (!yamlUpdated) {
+ if (argv.config) {
+ throw new Error(
+ `Internal error while adding framework ${library} ${libraryNames.join(" ")} to config at ${argv.config}`
+ );
+ } else {
+ throw new Error(
+ `Internal error while adding framework ${library} ${libraryNames.join(" ")} to ui5.yaml`
+ );
+ }
+ } else {
+ process.stdout.write(`Updated configuration written to ${argv.config || "ui5.yaml"}`);
+ process.stdout.write("\n");
+ let logMessage = `Added framework ${library} ${libraryNames.join(" ")} as`;
+ if (development) {
+ logMessage += " development";
+ } else if (optional) {
+ logMessage += " optional";
+ }
+ logMessage += libraries.length === 1 ? " dependency": " dependencies";
+ process.stdout.write(logMessage);
+ process.stdout.write("\n");
+ }
+};
+
+export default addCommand;
diff --git a/packages/cli/lib/cli/commands/build.js b/packages/cli/lib/cli/commands/build.js
new file mode 100644
index 00000000000..df93ac5a12e
--- /dev/null
+++ b/packages/cli/lib/cli/commands/build.js
@@ -0,0 +1,202 @@
+import baseMiddleware from "../middlewares/base.js";
+
+const build = {
+ command: "build",
+ describe: "Build project in current directory",
+ handler: handleBuild,
+ middlewares: [baseMiddleware]
+};
+
+build.builder = function(cli) {
+ return cli
+ .command("jsdoc", "Build JSDoc resources", {
+ handler: handleBuild,
+ builder: noop,
+ middlewares: [baseMiddleware]
+ })
+ .command("preload", "(default) Build project and create preload bundles", {
+ handler: handleBuild,
+ builder: noop,
+ middlewares: [baseMiddleware]
+ })
+ .command("self-contained",
+ "Build project and create self-contained bundle. " +
+ "Recommended to be used in conjunction with --include-all-dependencies", {
+ handler: handleBuild,
+ builder: noop,
+ middlewares: [baseMiddleware]
+ })
+ .option("include-all-dependencies", {
+ describe: "Include all dependencies in the build result. " +
+ "This is equivalent to '--include-dependency \"*\"'",
+ alias: ["all", "a"],
+ default: false,
+ type: "boolean"
+ })
+ .option("include-dependency", {
+ describe: "A list of dependencies to be included in the build result. You can use the asterisk '*' as" +
+ " an alias for including all dependencies in the build result. The listed dependencies cannot be" +
+ " overruled by dependencies defined in 'exclude-dependency'. " +
+ "The provided name must match with the dependency name shown in 'ui5 ls --flat'",
+ type: "string",
+ array: true
+ })
+ .option("include-dependency-regexp", {
+ describe: "A list of regular expressions defining dependencies to be included in the build result." +
+ " This list is prioritized like 'include-dependency'.",
+ type: "string",
+ array: true
+ })
+ .option("include-dependency-tree", {
+ describe: "A list of dependencies to be included in the build result. Transitive dependencies are" +
+ " implicitly included and do not need to be part of this list. These dependencies overrule" +
+ " the selection of 'exclude-dependency-tree' but can be overruled by 'exclude-dependency'.",
+ type: "string",
+ array: true
+ })
+ .option("exclude-dependency", {
+ describe: "A list of dependencies to be excluded from the build result. The listed dependencies can" +
+ " be overruled by dependencies defined in 'include-dependency'. " +
+ "The provided name must match with the dependency name shown in 'ui5 ls --flat'",
+ type: "string",
+ array: true
+ })
+ .option("exclude-dependency-regexp", {
+ describe: "A list of regular expressions defining dependencies to be excluded from the build result." +
+ " This list is prioritized like 'exclude-dependency'.",
+ type: "string",
+ array: true
+ })
+ .option("exclude-dependency-tree", {
+ describe: "A list of dependencies to be excluded from the build result. Transitive dependencies are" +
+ " implicitly included and do not need to be part of this list.",
+ type: "string",
+ array: true
+ })
+ .option("dest", {
+ describe: "Path of build destination",
+ default: "./dist",
+ type: "string"
+ })
+ .option("clean-dest", {
+ describe: "If present, clean the destination directory before building",
+ default: false,
+ type: "boolean"
+ })
+ .option("create-build-manifest", {
+ describe: "Store build metadata in a '.ui5' directory in the build destination, " +
+ "allowing reuse of the build result in other builds",
+ default: false,
+ type: "boolean"
+ })
+ .option("include-task", {
+ describe: "A list of tasks to be added to the default execution set. " +
+ "This option takes precedence over any excludes.",
+ type: "string",
+ array: true
+ })
+ .option("exclude-task", {
+ describe: "A list of tasks to be excluded from the default task execution set",
+ type: "string",
+ array: true
+ })
+ .option("framework-version", {
+ describe: "Overrides the framework version defined by the project. " +
+ "Takes the same value as the version part of \"ui5 use\"",
+ type: "string"
+ })
+ .option("cache-mode", {
+ describe:
+ "Cache mode to use when consuming SNAPSHOT versions of framework dependencies. " +
+ "The 'Default' behavior is to invalidate the cache after 9 hours. 'Force' uses the cache only and " +
+ "does not create any requests. 'Off' invalidates any existing cache and updates from the repository",
+ type: "string",
+ default: "Default",
+ choices: ["Default", "Force", "Off"]
+ })
+ .option("experimental-css-variables", {
+ describe:
+ "Generate CSS variables (css-variables.css, css-variables.source.less)" +
+ " and skeleton (library-skeleton(-RTL).css) for all themes",
+ default: false,
+ type: "boolean"
+ })
+ .option("output-style", {
+ describe:
+ "Processes build results into a specific directory structure. " +
+ "- Flat: Omits the project namespace and the \"resources\" directory. " +
+ "- Namespace: Respects the project namespace and the \"resources\" directory, " +
+ "maintaining the original structure. " +
+ "- Default: The default directory structure for every project type. For applications, " +
+ "this is identical to \"Flat\", and for libraries, it is \"Namespace\". Other types have a " +
+ "more distinct default output style.",
+ type: "string",
+ default: "Default",
+ choices: ["Default", "Flat", "Namespace"],
+ })
+ .coerce("output-style", (opt) => {
+ return opt.charAt(0).toUpperCase() + opt.slice(1).toLowerCase();
+ })
+ .example("ui5 build", "Preload build for project without dependencies")
+ .example("ui5 build self-contained", "Self-contained build for project")
+ .example("ui5 build --exclude-task=* --include-task=minify generateComponentPreload",
+ "Build project but only apply the minify- and generateComponentPreload tasks")
+ .example("ui5 build --include-task=minify --exclude-task=generateComponentPreload",
+ "Build project by applying all default tasks including the minify " +
+ "task and excluding the generateComponentPreload task")
+ .example("ui5 build --experimental-css-variables",
+ "Preload build with experimental CSS variables artifacts");
+};
+
+async function handleBuild(argv) {
+ const {graphFromStaticFile, graphFromPackageDependencies} = await import("@ui5/project/graph");
+
+ const command = argv._[argv._.length - 1];
+
+ let graph;
+ if (argv.dependencyDefinition) {
+ graph = await graphFromStaticFile({
+ filePath: argv.dependencyDefinition,
+ rootConfigPath: argv.config,
+ versionOverride: argv.frameworkVersion,
+ cacheMode: argv.cacheMode,
+ });
+ } else {
+ graph = await graphFromPackageDependencies({
+ rootConfigPath: argv.config,
+ versionOverride: argv.frameworkVersion,
+ cacheMode: argv.cacheMode,
+ workspaceConfigPath: argv.workspaceConfig,
+ workspaceName: argv.workspace === false ? null : argv.workspace,
+ });
+ }
+ const buildSettings = graph.getRoot().getBuilderSettings() || {};
+ await graph.build({
+ graph,
+ destPath: argv.dest,
+ cleanDest: argv["clean-dest"],
+ createBuildManifest: argv["create-build-manifest"],
+ dependencyIncludes: {
+ includeAllDependencies: argv["include-all-dependencies"],
+ includeDependency: argv["include-dependency"],
+ includeDependencyRegExp: argv["include-dependency-regexp"],
+ includeDependencyTree: argv["include-dependency-tree"],
+ excludeDependency: argv["exclude-dependency"],
+ excludeDependencyRegExp: argv["exclude-dependency-regexp"],
+ excludeDependencyTree: argv["exclude-dependency-tree"],
+ defaultIncludeDependency: buildSettings.includeDependency,
+ defaultIncludeDependencyRegExp: buildSettings.includeDependencyRegExp,
+ defaultIncludeDependencyTree: buildSettings.includeDependencyTree
+ },
+ selfContained: command === "self-contained",
+ jsdoc: command === "jsdoc",
+ includedTasks: argv["include-task"],
+ excludedTasks: argv["exclude-task"],
+ cssVariables: argv["experimental-css-variables"],
+ outputStyle: argv["output-style"],
+ });
+}
+
+function noop() {}
+
+export default build;
diff --git a/packages/cli/lib/cli/commands/config.js b/packages/cli/lib/cli/commands/config.js
new file mode 100644
index 00000000000..131d615f55f
--- /dev/null
+++ b/packages/cli/lib/cli/commands/config.js
@@ -0,0 +1,89 @@
+import chalk from "chalk";
+import process from "node:process";
+import baseMiddleware from "../middlewares/base.js";
+import Configuration from "@ui5/project/config/Configuration";
+
+const configCommand = {
+ command: "config",
+ describe: "Get and set UI5 CLI configuration options",
+ middlewares: [baseMiddleware],
+ handler: handleConfig
+};
+
+configCommand.builder = function(cli) {
+ return cli
+ .demandCommand(1, "Command required. Available commands are 'set', 'get', and 'list'")
+ .command("set [value]", "Set the value for a given configuration option. " +
+ "Clear an existing configuration by omitting the value", {
+ handler: handleConfig,
+ builder: (cli) => {
+ cli.positional("option", {
+ choices: Configuration.OPTIONS
+ });
+ },
+ middlewares: [baseMiddleware],
+ })
+ .command("get ", "Get the value for a given configuration option", {
+ handler: handleConfig,
+ builder: noop,
+ middlewares: [baseMiddleware],
+ })
+ .command("list", "Display the current configuration", {
+ handler: handleConfig,
+ builder: noop,
+ middlewares: [baseMiddleware],
+ })
+ .example("$0 config set ui5DataDir /path/to/.ui5",
+ "Set a value for the ui5DataDir configuration")
+ .example("$0 config set ui5DataDir",
+ "Unset the current value of the ui5DataDir configuration");
+};
+
+function noop() {}
+
+async function handleConfig(argv) {
+ const {_: commandArgs, option, value} = argv;
+ const command = commandArgs[commandArgs.length - 1];
+
+ // Yargs ensures that:
+ // - "option" only contains valid values (defined as "choices" in command builder)
+ // - "command" is one of "list", "get", "set"
+
+ const config = await Configuration.fromFile();
+ let jsonConfig;
+
+ switch (command) {
+ case "list":
+ // Print all configuration values to stdout
+ process.stdout.write(formatJsonForOutput(config.toJson()));
+ break;
+ case "get":
+ // Get a single configuration value and print to stdout
+ process.stdout.write(`${config.toJson()[option] ?? ""}\n`);
+ break;
+ case "set":
+ jsonConfig = config.toJson();
+ if (value === undefined || value === "") {
+ delete jsonConfig[option];
+ process.stderr.write(`Configuration option ${chalk.bold(option)} has been unset\n`);
+ } else {
+ jsonConfig[option] = value;
+ process.stderr.write(`Configuration option ${chalk.bold(option)} has been updated:
+${formatJsonForOutput(jsonConfig, option)}`);
+ }
+
+ await Configuration.toFile(new Configuration(jsonConfig));
+ break;
+ }
+}
+
+function formatJsonForOutput(config, filterKey) {
+ return Object.keys(config)
+ .filter((key) => !filterKey || filterKey === key)
+ .filter((key) => config[key] !== undefined) // Don't print undefined config values
+ .map((key) => {
+ return ` ${key} = ${config[key]}\n`;
+ }).join("");
+}
+
+export default configCommand;
diff --git a/packages/cli/lib/cli/commands/init.js b/packages/cli/lib/cli/commands/init.js
new file mode 100644
index 00000000000..5985c4f07c0
--- /dev/null
+++ b/packages/cli/lib/cli/commands/init.js
@@ -0,0 +1,32 @@
+// Init
+import baseMiddleware from "../middlewares/base.js";
+
+const initCommand = {
+ command: "init",
+ describe: "Initialize the UI5 CLI configuration for an application or library project.",
+ middlewares: [baseMiddleware]
+};
+
+initCommand.handler = async function() {
+ const {exists} = await import("../../utils/fsHelper.js");
+ const {default: init} = await import("../../init/init.js");
+ const {default: path} = await import("node:path");
+ const {writeFile} = await import("node:fs/promises");
+ const {default: jsYaml} = await import("js-yaml");
+
+ const yamlPath = path.resolve("./ui5.yaml");
+ if (await exists(yamlPath)) {
+ throw new Error("Initialization not possible: ui5.yaml already exists");
+ }
+
+ const projectConfig = await init();
+ const yaml = jsYaml.dump(projectConfig, {quotingType: `"`});
+
+ await writeFile(yamlPath, yaml);
+ process.stdout.write(`Wrote ui5.yaml to ${yamlPath}:`);
+ process.stdout.write("\n");
+ process.stdout.write(yaml);
+ process.stdout.write("\n");
+};
+
+export default initCommand;
diff --git a/packages/cli/lib/cli/commands/remove.js b/packages/cli/lib/cli/commands/remove.js
new file mode 100644
index 00000000000..3665c676f64
--- /dev/null
+++ b/packages/cli/lib/cli/commands/remove.js
@@ -0,0 +1,71 @@
+// Remove
+import baseMiddleware from "../middlewares/base.js";
+
+const removeCommand = {
+ command: "remove ",
+ describe: "Remove SAPUI5/OpenUI5 framework libraries from the project configuration.",
+ middlewares: [baseMiddleware]
+};
+
+removeCommand.builder = function(cli) {
+ return cli
+ .positional("framework-libraries", {
+ describe: "Framework library names",
+ type: "string"
+ })
+ .example("$0 remove sap.ui.core sap.m", "Remove the framework libraries sap.ui.core and sap.m as dependencies");
+};
+
+removeCommand.handler = async function(argv) {
+ let libraryNames = argv["framework-libraries"] || [];
+
+ if (libraryNames.length === 0) {
+ // Should not happen via yargs as parameter is mandatory
+ throw new Error("Missing mandatory parameter framework-libraries");
+ }
+
+ // filter duplicates
+ libraryNames = libraryNames.filter((libraryName, index) => {
+ return libraryNames.indexOf(libraryName) === index;
+ });
+
+ const projectGraphOptions = {
+ dependencyDefinition: argv.dependencyDefinition,
+ config: argv.config
+ };
+
+ const libraries = libraryNames.map((name) => {
+ const library = {name};
+ return library;
+ });
+
+ const {default: remove} = await import("../../framework/remove.js");
+
+ const {yamlUpdated} = await remove({
+ projectGraphOptions,
+ libraries
+ });
+
+ const library = libraries.length === 1 ? "library": "libraries";
+ if (!yamlUpdated) {
+ if (argv.config) {
+ throw new Error(
+ `Internal error while removing framework ${library} ${libraryNames.join(" ")} ` +
+ `to config at ${argv.config}`
+ );
+ } else {
+ throw new Error(
+ `Internal error while removing framework ${library} ${libraryNames.join(" ")} to ui5.yaml`
+ );
+ }
+ } else {
+ process.stdout.write(`Updated configuration written to ${argv.config || "ui5.yaml"}`);
+ process.stdout.write("\n");
+ let logMessage = `Removed framework ${library} ${libraryNames.join(" ")} as`;
+ logMessage += libraries.length === 1 ? " dependency": " dependencies";
+ process.stdout.write(logMessage);
+ process.stdout.write("\n");
+ }
+};
+
+export default removeCommand;
diff --git a/packages/cli/lib/cli/commands/serve.js b/packages/cli/lib/cli/commands/serve.js
new file mode 100644
index 00000000000..4719e82bf34
--- /dev/null
+++ b/packages/cli/lib/cli/commands/serve.js
@@ -0,0 +1,188 @@
+import path from "node:path";
+import os from "node:os";
+import chalk from "chalk";
+import baseMiddleware from "../middlewares/base.js";
+
+// Serve
+const serve = {
+ command: "serve",
+ describe: "Start a web server for the current project",
+ middlewares: [baseMiddleware]
+};
+
+serve.builder = function(cli) {
+ return cli
+ .option("port", {
+ describe: "Port to bind on (default for HTTP: 8080, HTTP/2: 8443)",
+ alias: "p",
+ type: "number"
+ })
+ .option("open", {
+ describe:
+ "Open web server root directory in default browser. " +
+ "Optionally, supplied relative path will be appended to the root URL",
+ alias: "o",
+ type: "string"
+ })
+ .option("h2", {
+ describe: "Shortcut for enabling the HTTP/2 protocol for the web server",
+ default: false,
+ type: "boolean"
+ })
+ .option("simple-index", {
+ describe: "Use a simplified view for the server directory listing",
+ default: false,
+ type: "boolean"
+ })
+ .option("accept-remote-connections", {
+ describe: "Accept remote connections. By default the server only accepts connections from localhost",
+ default: false,
+ type: "boolean"
+ })
+ .option("key", {
+ describe: "Path to the private key",
+ default: path.join(os.homedir(), ".ui5", "server", "server.key"),
+ type: "string"
+ })
+ .option("cert", {
+ describe: "Path to the certificate",
+ default: path.join(os.homedir(), ".ui5", "server", "server.crt"),
+ type: "string"
+ })
+ .option("sap-csp-policies", {
+ describe:
+ "Always send content security policies 'sap-target-level-1' and " +
+ "'sap-target-level-3' in report-only mode",
+ default: false,
+ type: "boolean"
+ })
+ .option("serve-csp-reports", {
+ describe: "Collects and serves CSP reports upon request to '/.ui5/csp/csp-reports.json'",
+ default: false,
+ type: "boolean"
+ })
+ .option("framework-version", {
+ describe: "Overrides the framework version defined by the project. " +
+ "Takes the same value as the version part of \"ui5 use\"",
+ type: "string"
+ })
+ .option("cache-mode", {
+ describe:
+ "Cache mode to use when consuming SNAPSHOT versions of framework dependencies. " +
+ "The 'Default' behavior is to invalidate the cache after 9 hours. 'Force' uses the cache only and " +
+ "does not create any requests. 'Off' invalidates any existing cache and updates from the repository",
+ type: "string",
+ default: "Default",
+ choices: ["Default", "Force", "Off"]
+ })
+ .example("ui5 serve", "Start a web server for the current project")
+ .example("ui5 serve --h2", "Enable the HTTP/2 protocol for the web server (requires SSL certificate)")
+ .example("ui5 serve --config /path/to/ui5.yaml", "Use the project configuration from a custom path")
+ .example("ui5 serve --dependency-definition /path/to/projectDependencies.yaml",
+ "Use a static dependency definition file")
+ .example("ui5 serve --port 1337 --open tests/QUnit.html",
+ "Listen to port 1337 and launch default browser with http://localhost:1337/test/QUnit.html");
+};
+
+serve.handler = async function(argv) {
+ const {graphFromStaticFile, graphFromPackageDependencies} = await import("@ui5/project/graph");
+ const {serve: serverServe} = await import("@ui5/server");
+ const {getSslCertificate} = await import("@ui5/server/internal/sslUtil");
+
+ let graph;
+ if (argv.dependencyDefinition) {
+ graph = await graphFromStaticFile({
+ filePath: argv.dependencyDefinition,
+ rootConfigPath: argv.config,
+ versionOverride: argv.frameworkVersion,
+ cacheMode: argv.cacheMode,
+ });
+ } else {
+ graph = await graphFromPackageDependencies({
+ rootConfigPath: argv.config,
+ versionOverride: argv.frameworkVersion,
+ cacheMode: argv.cacheMode,
+ workspaceConfigPath: argv.workspaceConfig,
+ workspaceName: argv.workspace === false ? null : argv.workspace,
+ });
+ }
+
+ let port = argv.port;
+ let changePortIfInUse = false;
+
+ if (!port && graph.getRoot().getServerSettings()) {
+ const serverSettings = graph.getRoot().getServerSettings();
+ if (argv.h2) {
+ port = serverSettings.httpsPort;
+ } else {
+ port = serverSettings.httpPort;
+ }
+ }
+
+ if (!port) {
+ changePortIfInUse = true; // only change if port isn't explicitly set
+ if (argv.h2) {
+ port = 8443;
+ } else {
+ port = 8080;
+ }
+ }
+
+ const serverConfig = {
+ port,
+ changePortIfInUse,
+ h2: argv.h2,
+ simpleIndex: !!argv.simpleIndex,
+ acceptRemoteConnections: !!argv.acceptRemoteConnections,
+ cert: argv.h2 ? argv.cert : undefined,
+ key: argv.h2 ? argv.key : undefined,
+ sendSAPTargetCSP: !!argv.sapCspPolicies,
+ serveCSPReports: !!argv.serveCspReports
+ };
+
+ if (serverConfig.h2) {
+ const {key, cert} = await getSslCertificate(serverConfig.key, serverConfig.cert);
+ serverConfig.key = key;
+ serverConfig.cert = cert;
+ }
+
+ const {h2, port: actualPort} = await serverServe(graph, serverConfig);
+
+ const protocol = h2 ? "https" : "http";
+ let browserUrl = protocol + "://localhost:" + actualPort;
+ if (argv.acceptRemoteConnections) {
+ process.stderr.write("\n");
+ process.stderr.write(chalk.bold("⚠️ This server is accepting connections from all hosts on your network"));
+ process.stderr.write("\n");
+ process.stderr.write(chalk.dim.underline("Please Note:"));
+ process.stderr.write("\n");
+ process.stderr.write(chalk.bold.dim(
+ "* This server is intended for development purposes only. Do not use it in production."));
+ process.stderr.write("\n");
+ process.stderr.write(chalk.dim(
+ "* Vulnerable (custom-)middleware can pose a threat to your system when exposed to the network"));
+ process.stderr.write("\n");
+ process.stderr.write(chalk.dim(
+ "* The use of proxy-middleware with preconfigured credentials might enable unauthorized access " +
+ "to a target system for third parties on your network"));
+ process.stderr.write("\n\n");
+ }
+ process.stdout.write("Server started");
+ process.stdout.write("\n");
+ process.stdout.write("URL: " + browserUrl);
+ process.stdout.write("\n");
+
+ if (argv.open !== undefined) {
+ if (typeof argv.open === "string") {
+ let relPath = argv.open || "/";
+ if (!relPath.startsWith("/")) {
+ relPath = "/" + relPath;
+ }
+ browserUrl += relPath;
+ }
+ const {default: open} = await import("open");
+ open(browserUrl);
+ }
+};
+
+export default serve;
diff --git a/packages/cli/lib/cli/commands/tree.js b/packages/cli/lib/cli/commands/tree.js
new file mode 100644
index 00000000000..e683a72b676
--- /dev/null
+++ b/packages/cli/lib/cli/commands/tree.js
@@ -0,0 +1,173 @@
+// Tree
+import baseMiddleware from "../middlewares/base.js";
+import chalk from "chalk";
+
+const tree = {
+ command: "tree",
+ aliases: ["ls", "list"],
+ describe:
+ "Outputs the dependency tree of the current project to stdout. " +
+ "It takes all relevant parameters of ui5 build into account.",
+ middlewares: [baseMiddleware]
+};
+
+tree.builder = function(cli) {
+ return cli
+ .option("flat", {
+ describe: "Output a flat list of all dependencies instead of a tree hierarchy",
+ type: "boolean",
+ default: false
+ })
+ .option("level", {
+ describe: "Limit the number of levels shown in the tree hierarchy",
+ type: "number"
+ })
+ .option("framework-version", {
+ describe:
+ "Overrides the framework version defined by the project. " +
+ "Takes the same value as the version part of \"ui5 use\"",
+ type: "string"
+ })
+ .option("cache-mode", {
+ describe:
+ "Cache mode to use when consuming SNAPSHOT versions of framework dependencies. " +
+ "The 'Default' behavior is to invalidate the cache after 9 hours. 'Force' uses the cache only and " +
+ "does not create any requests. 'Off' invalidates any existing cache and updates from the repository",
+ type: "string",
+ default: "Default",
+ choices: ["Default", "Force", "Off"]
+ });
+};
+
+tree.handler = async function(argv) {
+ let startTime;
+ let elapsedTime;
+ if (argv.perf) {
+ startTime = process.hrtime();
+ }
+ const {graphFromStaticFile, graphFromPackageDependencies} = await import("@ui5/project/graph");
+ let graph;
+ if (argv.dependencyDefinition) {
+ graph = await graphFromStaticFile({
+ filePath: argv.dependencyDefinition,
+ versionOverride: argv.frameworkVersion,
+ cacheMode: argv.cacheMode,
+ });
+ } else {
+ graph = await graphFromPackageDependencies({
+ rootConfigPath: argv.config,
+ versionOverride: argv.frameworkVersion,
+ cacheMode: argv.cacheMode,
+ workspaceConfigPath: argv.workspaceConfig,
+ workspaceName: argv.workspace === false ? null : argv.workspace,
+ });
+ }
+
+ if (argv.perf) {
+ elapsedTime = await getElapsedTime(startTime);
+ }
+
+ let requestedLevels;
+ if (argv.level !== undefined && isNaN(argv.level)) {
+ throw new Error(`The provided 'level' option is not a number`);
+ } else if (argv.level !== undefined) {
+ requestedLevels = argv.level;
+ } else {
+ requestedLevels = Infinity;
+ }
+
+ const projects = new Map();
+ const indentWidth = 4;
+ await graph.traverseBreadthFirst(async ({project, dependencies}) => {
+ projects.set(project.getName(), {
+ render: function(level, connectorIndices, lastChild, renderDeps = true) {
+ let baseString = " ".repeat(level * indentWidth);
+ connectorIndices.forEach((idx) => {
+ baseString = `${baseString.slice(0, idx)}│${baseString.slice(idx + 1)}`;
+ });
+ const connectorString = lastChild ? "╰─" : "├─";
+ let name = chalk.bold(project.getName());
+ if (project.isFrameworkProject()) {
+ name = chalk.blue(name);
+ }
+ process.stdout.write(
+ `${baseString}${connectorString} ${name} ` +
+ `${project.getNamespace() ? chalk.inverse(project.getNamespace()) + " " : ""}` +
+ chalk.dim(`(${project.getVersion()}, ${project.getType()}) `) +
+ chalk.dim.italic(`${project.getRootPath()}`)
+ );
+ process.stdout.write("\n");
+
+ const lastIdx = dependencies.length - 1;
+ const newConnectorIndices = [...connectorIndices];
+ if (!lastChild) {
+ newConnectorIndices.push(level * indentWidth);
+ }
+
+ if (level >= requestedLevels) {
+ const msg = chalk.dim.italic(`Dependencies below Level ${level} are hidden`);
+ let nextBaseString = " ".repeat((level + 1) * indentWidth);
+ newConnectorIndices.forEach((idx) => {
+ nextBaseString = `${nextBaseString.slice(0, idx)}│${nextBaseString.slice(idx + 1)}`;
+ });
+ process.stdout.write(`${nextBaseString}╰─ ${msg}`);
+ process.stdout.write("\n");
+ return;
+ }
+ if (renderDeps) {
+ dependencies.forEach((dep, i) => {
+ projects.get(dep).render(level + 1, newConnectorIndices, i === lastIdx);
+ });
+ }
+ }
+ });
+ });
+
+ process.stdout.write(chalk.bold.underline(`Dependencies (${projects.size}):`));
+ process.stdout.write("\n");
+ if (argv.flat) {
+ // Iterate over list of projects, rendering each individually
+ // We need to transform the map into an array in order to know the index
+ // for determining whether we are rendering the last entry (lastChild param)
+ Array.from(projects.values()).forEach(({render: renderProject}, idx, arr) => {
+ renderProject(0, [], idx == arr.length -1, false);
+ });
+ } else {
+ // Recursively render the tree, starting with the first entry of the map
+ projects.values().next().value.render(0, [], true);
+ }
+ process.stdout.write("\n");
+
+ const extensionNames = graph.getExtensionNames();
+ const extensionCount = extensionNames.length;
+ process.stdout.write(chalk.bold.underline(`Extensions (${extensionCount}):`));
+ process.stdout.write("\n");
+ if (extensionCount) {
+ const lastIdx = extensionCount - 1;
+ extensionNames.forEach((extensionName, idx) => {
+ const extension = graph.getExtension(extensionName);
+ const connectorString = idx === lastIdx ? "╰─" : "├─";
+ process.stdout.write(
+ `${connectorString} ${extensionName} ` +
+ chalk.dim(`(${extension.getVersion()}, ${extension.getType()}) `) +
+ chalk.dim.italic(`${extension.getRootPath()}`));
+ process.stdout.write("\n");
+ });
+ } else {
+ process.stdout.write(chalk.italic(`None`));
+ process.stdout.write("\n");
+ }
+ if (argv.perf) {
+ process.stderr.write("\n");
+ process.stderr.write(chalk.blue(
+ `Dependency graph generation took ${chalk.bold(elapsedTime)}`));
+ process.stderr.write("\n");
+ }
+};
+
+async function getElapsedTime(startTime) {
+ const timeDiff = process.hrtime(startTime);
+ const {default: prettyHrtime} = await import("pretty-hrtime");
+ return prettyHrtime(timeDiff);
+}
+export default tree;
diff --git a/packages/cli/lib/cli/commands/use.js b/packages/cli/lib/cli/commands/use.js
new file mode 100644
index 00000000000..f30f64d72b5
--- /dev/null
+++ b/packages/cli/lib/cli/commands/use.js
@@ -0,0 +1,91 @@
+// Use
+import baseMiddleware from "../middlewares/base.js";
+
+const useCommand = {
+ command: "use ",
+ describe: "Initialize or update the project's framework configuration.",
+ middlewares: [baseMiddleware]
+};
+
+useCommand.builder = function(cli) {
+ return cli
+ .positional("framework-info", {
+ describe: "Framework name, version or both (name@version).\n" +
+ "Name can be \"SAPUI5\" or \"OpenUI5\" (case-insensitive).\n" +
+ "Version can be \"latest\" (default), a version or range according to the Semantic Versioning specification (https://semver.org/), " +
+ "or a tag available in the npm registry.\n" +
+ "For SAP-internal usage the version can also be \"latest-snapshot\", " +
+ "a version or range ending with -SNAPSHOT, " +
+ "or a simplified range such as \"1-SNAPSHOT\", \"1.x-SNAPSHOT\" or \"1.108-SNAPSHOT\".",
+ type: "string"
+ })
+ .example("$0 use sapui5@latest", "Use SAPUI5 in the latest available version")
+ .example("$0 use openui5@1.76", "Use OpenUI5 in the latest available 1.76 patch version")
+ .example("$0 use latest", "Use the latest available version of the configured framework")
+ .example("$0 use openui5", "Use OpenUI5 in the latest available version");
+};
+
+function parseFrameworkInfo(frameworkInfo) {
+ const parts = frameworkInfo.split("@");
+ if (parts.length > 2) {
+ // More than one @ sign
+ throw new Error("Invalid framework info: " + frameworkInfo);
+ }
+ if (parts.length === 1) {
+ // No @ sign, only name or version
+ const nameOrVersion = parts[0];
+ if (!nameOrVersion) {
+ throw new Error("Invalid framework info: " + frameworkInfo);
+ }
+ if (["sapui5", "openui5"].includes(nameOrVersion.toLowerCase())) {
+ // Framework name without version uses "latest", similar to npm install behavior
+ return {
+ name: nameOrVersion,
+ version: "latest"
+ };
+ } else {
+ return {
+ name: null,
+ version: nameOrVersion
+ };
+ }
+ } else {
+ const [name, version] = parts;
+ if (!name || !version) {
+ throw new Error("Invalid framework info: " + frameworkInfo);
+ }
+ return {name, version};
+ }
+}
+
+useCommand.handler = async function(argv) {
+ const frameworkOptions = parseFrameworkInfo(argv["framework-info"]);
+
+ const projectGraphOptions = {
+ dependencyDefinition: argv.dependencyDefinition,
+ config: argv.config
+ };
+
+ const {default: use} = await import("../../framework/use.js");
+ const {usedFramework, usedVersion, yamlUpdated} = await use({
+ projectGraphOptions,
+ frameworkOptions
+ });
+
+ if (!yamlUpdated) {
+ if (argv.config) {
+ throw new Error(
+ `Internal error while updating config at ${argv.config} to ${usedFramework} version ${usedVersion}`
+ );
+ } else {
+ throw new Error(`Internal error while updating ui5.yaml to ${usedFramework} version ${usedVersion}`);
+ }
+ } else {
+ process.stdout.write(`Updated configuration written to ${argv.config || "ui5.yaml"}`);
+ process.stdout.write("\n");
+ process.stdout.write(`This project is now using ${usedFramework} version ${usedVersion}`);
+ process.stdout.write("\n");
+ }
+};
+
+export default useCommand;
diff --git a/packages/cli/lib/cli/commands/versions.js b/packages/cli/lib/cli/commands/versions.js
new file mode 100644
index 00000000000..31b52db8f04
--- /dev/null
+++ b/packages/cli/lib/cli/commands/versions.js
@@ -0,0 +1,50 @@
+import baseMiddleware from "../middlewares/base.js";
+import path from "node:path";
+import {isLogLevelEnabled} from "@ui5/logger";
+import {createRequire} from "node:module";
+
+// Using CommonsJS require since JSON module imports are still experimental
+const require = createRequire(import.meta.url);
+
+const versions = {
+ command: "versions",
+ describe: "Shows the versions of all UI5 CLI modules",
+ middlewares: [baseMiddleware]
+};
+
+const NOT_FOUND = "===(not installed)";
+versions.getVersion = (pkg) => {
+ try {
+ const packageInfo = require(`${pkg}/package.json`);
+ if (!packageInfo?.version) {
+ return NOT_FOUND;
+ }
+ let res = packageInfo.version;
+ if (isLogLevelEnabled("verbose")) {
+ const packageDir = path.dirname(require.resolve(`${pkg}/package.json`));
+ res += ` (from ${packageDir})`;
+ }
+ return res;
+ } catch {
+ return NOT_FOUND;
+ }
+};
+
+versions.handler = async function() {
+ const output = (await Promise.all(
+ [
+ "@ui5/cli",
+ "@ui5/builder",
+ "@ui5/server",
+ "@ui5/fs",
+ "@ui5/project",
+ "@ui5/logger",
+ ].map(async (id) => {
+ return (id + ":").padEnd(15) + versions.getVersion(id);
+ })
+ )).join("\n");
+
+ process.stdout.write(`\n${output}\n\n`);
+};
+
+export default versions;
diff --git a/packages/cli/lib/cli/middlewares/base.js b/packages/cli/lib/cli/middlewares/base.js
new file mode 100644
index 00000000000..6140d967444
--- /dev/null
+++ b/packages/cli/lib/cli/middlewares/base.js
@@ -0,0 +1,13 @@
+import {initLogger} from "./logger.js";
+/**
+ * Base middleware for CLI commands.
+ *
+ * This middleware should be executed for every CLI command to enable basic features (e.g. logging).
+ *
+ * @param {object} argv The CLI arguments
+ * @returns {object}
+ */
+export default async function(argv) {
+ await initLogger(argv);
+ return {};
+}
diff --git a/packages/cli/lib/cli/middlewares/logger.js b/packages/cli/lib/cli/middlewares/logger.js
new file mode 100644
index 00000000000..24def1939c5
--- /dev/null
+++ b/packages/cli/lib/cli/middlewares/logger.js
@@ -0,0 +1,33 @@
+import {setLogLevel, isLogLevelEnabled, getLogger} from "@ui5/logger";
+import ConsoleWriter from "@ui5/logger/writers/Console";
+import {getVersion} from "../version.js";
+/**
+ * Logger middleware to enable logging capabilities
+ *
+ * @param {object} argv logger arguments
+ */
+export async function initLogger(argv) {
+ if (argv.silent) {
+ setLogLevel("silent");
+ }
+ if (argv.perf) {
+ setLogLevel("perf");
+ }
+ if (argv.verbose) {
+ setLogLevel("verbose");
+ }
+ if (argv.loglevel && argv.loglevel !== "info") {
+ // argv.loglevel defaults to "info", which is anyways already the Logger's default
+ // Therefore do not explicitly set it again in order to allow overwriting the log level
+ // using the UI5_LOG_LVL environment variable
+ setLogLevel(argv.loglevel);
+ }
+
+ // Initialize writer
+ ConsoleWriter.init();
+ if (isLogLevelEnabled("verbose")) {
+ const log = getLogger("cli:middlewares:base");
+ log.verbose(`using @ui5/cli version ${getVersion()}`);
+ log.verbose(`using node version ${process.version}`);
+ }
+}
diff --git a/packages/cli/lib/cli/version.js b/packages/cli/lib/cli/version.js
new file mode 100644
index 00000000000..8446dc526ca
--- /dev/null
+++ b/packages/cli/lib/cli/version.js
@@ -0,0 +1,9 @@
+let version;
+
+// This module holds the CLI's version information (set via cli.js) for later retrieval (e.g. from middlewares/logger)
+export function setVersion(v) {
+ version = v;
+}
+export function getVersion() {
+ return version;
+}
diff --git a/packages/cli/lib/framework/add.js b/packages/cli/lib/framework/add.js
new file mode 100644
index 00000000000..fc884ac1410
--- /dev/null
+++ b/packages/cli/lib/framework/add.js
@@ -0,0 +1,87 @@
+import {getRootProjectConfiguration, createFrameworkResolverInstance} from "./utils.js";
+
+/**
+ * Adds the given set of libraries to the framework libraries section in the ui5.yaml
+ *
+ * @param {object} parameters Parameters
+ * @param {object} parameters.projectGraphOptions
+ * @param {object} parameters.libraries
+ */
+export default async function({projectGraphOptions, libraries}) {
+ const project = await getRootProjectConfiguration(projectGraphOptions);
+
+ if (project.getSpecVersion().lt("2.0")) {
+ throw new Error(
+ `ui5 add command requires specVersion "2.0" or higher. ` +
+ `Project ${project.getName()} uses specVersion "${project.getSpecVersion().toString()}"`
+ );
+ }
+
+ const frameworkName = project.getFrameworkName();
+ const frameworkVersion = project.getFrameworkVersion();
+
+ if (!frameworkName) {
+ throw new Error(
+ `Project ${project.getName()} is missing a framework configuration. ` +
+ `Please use "ui5 use" to configure a framework and version.`
+ );
+ }
+ if (!frameworkVersion) {
+ throw new Error(
+ `Project ${project.getName()} does not define a framework version configuration. ` +
+ `Please use "ui5 use" to configure a version.`
+ );
+ }
+
+ const resolver = await createFrameworkResolverInstance({
+ frameworkName, frameworkVersion
+ }, {
+ cwd: project.getRootPath()
+ });
+
+ // Get metadata of all libraries to verify that they can be installed
+ await Promise.all(libraries.map(async ({name}) => {
+ try {
+ await resolver.getLibraryMetadata(name);
+ } catch (err) {
+ throw new Error(`Failed to find ${frameworkName} framework library ${name}: ` + err.message);
+ }
+ }));
+
+ // Shallow copy of given libraries to not modify the input parameter when pushing other libraries
+ const allLibraries = [...libraries];
+
+ project.getFrameworkDependencies().forEach((library) => {
+ // Don't add libraries twice!
+ if (allLibraries.findIndex(($) => $.name === library.name) === -1) {
+ allLibraries.push(library);
+ }
+ });
+
+ allLibraries.sort((a, b) => {
+ return a.name.localeCompare(b.name);
+ });
+
+ // Try to update YAML file but still return with name and resolved version in case it failed
+ let yamlUpdated = false;
+ try {
+ const {default: updateYaml} = await import("./updateYaml.js");
+ await updateYaml({
+ project,
+ configPathOverride: projectGraphOptions.config,
+ data: {
+ framework: {
+ libraries: allLibraries
+ }
+ }
+ });
+ yamlUpdated = true;
+ } catch (err) {
+ if (err.name !== "FrameworkUpdateYamlFailed") {
+ throw err;
+ }
+ }
+ return {
+ yamlUpdated
+ };
+}
diff --git a/packages/cli/lib/framework/remove.js b/packages/cli/lib/framework/remove.js
new file mode 100644
index 00000000000..a7e2e9a5db8
--- /dev/null
+++ b/packages/cli/lib/framework/remove.js
@@ -0,0 +1,84 @@
+import {getRootProjectConfiguration} from "./utils.js";
+import {getLogger} from "@ui5/logger";
+
+const log = getLogger("cli:framework:remove");
+
+/**
+ * Removes the given set of libraries from the framework libraries section in the ui5.yaml
+ *
+ * @param {object} parameters Parameters
+ * @param {object} parameters.projectGraphOptions
+ * @param {object} parameters.libraries
+ */
+export default async function({projectGraphOptions, libraries}) {
+ const project = await getRootProjectConfiguration(projectGraphOptions);
+
+ if (project.getSpecVersion().lt("2.0")) {
+ throw new Error(
+ `ui5 remove command requires specVersion "2.0" or higher. ` +
+ `Project ${project.getName()} uses specVersion "${project.getSpecVersion().toString()}"`
+ );
+ }
+
+ if (!project.getFrameworkName()) {
+ throw new Error(
+ `Project ${project.getName()} is missing a framework configuration. ` +
+ `Please use "ui5 use" to configure a framework and version.`
+ );
+ }
+ if (!project.getFrameworkVersion()) {
+ throw new Error(
+ `Project ${project.getName()} does not define a framework version configuration. ` +
+ `Please use "ui5 use" to configure a version.`
+ );
+ }
+
+ if (!project.getFrameworkDependencies().length) {
+ throw new Error(
+ `Project ${project.getName()} does not define framework libraries.`
+ );
+ }
+
+ const allLibraries = [...project.getFrameworkDependencies()];
+
+ libraries.forEach((library) => {
+ const iIndexToRemove = allLibraries.findIndex(($) => $.name === library.name);
+ if (iIndexToRemove === -1) {
+ // do not fail here just log, because the framework library is not present afterwards
+ log.warn(
+ `Failed to remove framework library ${library.name} from project ` +
+ `${project.getName()} because it is not present.`
+ );
+ } else {
+ allLibraries.splice(iIndexToRemove, 1);
+ }
+ });
+
+
+ allLibraries.sort((a, b) => {
+ return a.name.localeCompare(b.name);
+ });
+
+ // Try to update YAML file but still return with name and resolved version in case it failed
+ let yamlUpdated = false;
+ try {
+ const {default: updateYaml} = await import("./updateYaml.js");
+ await updateYaml({
+ project,
+ configPathOverride: projectGraphOptions.config,
+ data: {
+ framework: {
+ libraries: allLibraries
+ }
+ }
+ });
+ yamlUpdated = true;
+ } catch (err) {
+ if (err.name !== "FrameworkUpdateYamlFailed") {
+ throw err;
+ }
+ }
+ return {
+ yamlUpdated
+ };
+}
diff --git a/packages/cli/lib/framework/updateYaml.js b/packages/cli/lib/framework/updateYaml.js
new file mode 100644
index 00000000000..12063245f91
--- /dev/null
+++ b/packages/cli/lib/framework/updateYaml.js
@@ -0,0 +1,291 @@
+import path from "node:path";
+import {readFile, writeFile} from "node:fs/promises";
+import {loadAll, dump} from "js-yaml";
+import {fromYaml, getPosition, getValue, getKind} from "data-with-position";
+import {getLogger} from "@ui5/logger";
+
+const log = getLogger("cli:framework:updateYaml");
+
+function getProjectYamlDocument({project, configFile, configPath}) {
+ const configs = loadAll(configFile, undefined, {
+ filename: configPath
+ });
+
+ const projectDocumentIndex = configs.findIndex((config) => {
+ return config.metadata && config.metadata.name === project.getName();
+ });
+ if (projectDocumentIndex === -1) {
+ throw new Error(
+ `Could not find project with name ${project.getName()} in YAML: ${configPath}`
+ );
+ }
+
+ const matchDocumentSeparator = /^---/gm;
+ let currentDocumentIndex = 0;
+ let currentIndex = 0;
+ let document;
+ while ((document = matchDocumentSeparator.exec(configFile)) !== null) {
+ // If the first separator is not at the beginning of the file
+ // we are already at document index 1
+ // Using String#trim() to remove any whitespace characters
+ if (currentDocumentIndex === 0 && configFile.substring(0, document.index).trim().length > 0) {
+ currentDocumentIndex = 1;
+ }
+
+ if (currentDocumentIndex === projectDocumentIndex) {
+ currentIndex = document.index;
+ break;
+ }
+
+ currentDocumentIndex++;
+ }
+
+ return {
+ projectDocumentContent: configFile.substring(currentIndex),
+ projectDocumentStartIndex: currentIndex
+ };
+}
+
+function applyChanges(string, changes) {
+ function positionToIndex(position) {
+ // Match the n-th line-ending to find the start of the given line
+ const lineStartPattern = new RegExp("(?:(?:\r?\n)([^\r\n]*)){" + (position.line - 1) + "}");
+ const lineStartMatch = lineStartPattern.exec(string);
+ if (!lineStartMatch) {
+ throw new Error("Could not find line start!");
+ }
+ // Add column number -1 (as column 1 starts at index 0)
+ return lineStartMatch.index + lineStartMatch[0].length - lineStartMatch[1].length + position.column - 1;
+ }
+
+ const indexReplacements = changes.map((change) => {
+ if (change.type === "update") {
+ return {
+ startIndex: positionToIndex(change.position.start),
+ endIndex: positionToIndex(change.position.end),
+ value: change.value
+ };
+ } else if (change.type === "insert") {
+ let startIndex = positionToIndex(change.parentPosition.end);
+ if (change.parentPosition.end.column > 1) {
+ // When end.column is not 1 we expect it to be the end of the line
+ // so the index needs to be increased by 1 to insert into the next line
+ startIndex++;
+ }
+ const endIndex = startIndex;
+ return {
+ startIndex,
+ endIndex,
+ value: change.value
+ };
+ }
+ }).sort((a, b) => {
+ // Sort descending by endIndex
+ // This means replacements are done from bottom to top to not affect length/index of upcoming replacements
+
+ if (a.endIndex < b.endIndex) {
+ return 1;
+ }
+ if (a.endIndex > b.endIndex) {
+ return -1;
+ }
+ return 0;
+ });
+
+ const array = Array.from(string);
+ indexReplacements.forEach((indexReplacement) => {
+ array.splice(
+ /* index */ indexReplacement.startIndex,
+ /* count */ indexReplacement.endIndex - indexReplacement.startIndex,
+ /* insert */ indexReplacement.value
+ );
+ });
+ return array.join("");
+}
+
+function getValueFromPath(data, path) {
+ return path.reduce((currentData, pathSegment) => {
+ return currentData[pathSegment];
+ }, data);
+}
+
+function getPositionFromPath(positionData, path) {
+ const data = getValueFromPath(positionData, path);
+ const position = getPosition(data);
+ const kind = getKind(data);
+ if ((kind === "array" && data.length) || kind === "object") {
+ // data-with-position treats arrays and objects different from primitives:
+ // The end index of such nodes always reaches up to the beginning of the following node, instead of the end
+ // of the contained data.
+ // For example, if an array has entries, the end position of the array is *directly* at the beginning of
+ // the next node instead of at the end of the last entry.
+ // Typically this means one line and multiple columns *after* the array ended.
+ // However, if an array has no entries (e.g. "[]"), the end is directly after the end of that data and
+ // *not* in the next line (this appears to be an inconsistency).
+ // Therefore, in case we encounter an array *with entries*, or an object, we reset the end column to "1"
+ // to prevent replacing (i.e. removing) the indentation of the following node.
+ position.end.column = 1;
+ }
+ return position;
+}
+
+function formatValue(value, indent) {
+ if (typeof value === "string") {
+ // TODO: Use better logic?
+ if (value.includes(".")) {
+ return ` "${value}"`; // Put quotes around versions
+ } else {
+ return " " + value;
+ }
+ } else if (typeof value === "object" && !Array.isArray(value)) {
+ let string = "\n";
+ Object.keys(value).forEach((key, i, arr) => {
+ const entry = value[key];
+ string += " ".repeat(indent) + key + ":" + formatValue(entry);
+ if (i < arr.length - 1) {
+ string += "\n";
+ }
+ });
+ return string;
+ } else if (Array.isArray(value)) {
+ const indentString = " ".repeat(indent);
+ const string = dump(value);
+ const arr = string.split("\n");
+ arr.pop();
+ return "\n" + indentString + arr.join("\n" + indentString) + "\n";
+ }
+}
+
+export default async function({project, configPathOverride, data}) {
+ let configPath;
+ if (configPathOverride) {
+ if (path.isAbsolute(configPathOverride)) {
+ configPath = configPathOverride;
+ } else {
+ configPath = path.join(project.getRootPath(), configPathOverride);
+ }
+ } else {
+ configPath = path.join(project.getRootPath(), "ui5.yaml");
+ }
+
+ const configFile = await readFile(configPath, {encoding: "utf8"});
+
+ let {
+ projectDocumentContent,
+ projectDocumentStartIndex
+ } = await getProjectYamlDocument({
+ project,
+ configFile,
+ configPath
+ });
+
+ const positionData = fromYaml(projectDocumentContent);
+
+ const changes = [];
+
+ function addInsert(entryPath, newValue) {
+ // New
+ const parentPath = entryPath.slice(0, -1);
+ const parentData = getValueFromPath(positionData, parentPath);
+ const parentPosition = getPosition(parentData);
+ const siblings = Object.keys(parentData);
+ let indent;
+ if (siblings.length === 0) {
+ indent = parentPosition.start.column - 1;
+ } else {
+ const firstSiblingPosition = getPosition(parentData[siblings[0]]);
+ indent = firstSiblingPosition.start.column - 1;
+ }
+ let value = `${" ".repeat(indent)}${entryPath[entryPath.length - 1]}:${formatValue(newValue, indent + 2)}`;
+ if (!value.endsWith("\n")) {
+ value += "\n";
+ }
+ changes.push({
+ type: "insert",
+ parentPosition,
+ value
+ });
+ }
+
+ function addUpdate(entryPath, newValue) {
+ const position = getPositionFromPath(positionData, entryPath);
+ // -1 as column 1 starts at index 0
+ const indent = position.start.column - 1;
+ changes.push({
+ type: "update",
+ position,
+ value: `${entryPath[entryPath.length - 1]}:${formatValue(newValue, indent + 2)}`
+ });
+ }
+
+ function addRemove(entryPath) {
+ const position = getPositionFromPath(positionData, entryPath);
+ const copyPosition = JSON.parse(JSON.stringify(position));
+ // set copyPosition to 1 to remove the indent
+ copyPosition.start.column = 1;
+ changes.push({
+ type: "update",
+ position: copyPosition,
+ value: ``
+ });
+ }
+
+ if (!positionData.framework) {
+ addInsert(["framework"], data.framework);
+ } else {
+ if (data.framework.name) {
+ if (!positionData.framework.name) {
+ addInsert(["framework", "name"], data.framework.name);
+ } else if (getValue(positionData.framework.name) !== data.framework.name) {
+ addUpdate(["framework", "name"], data.framework.name);
+ }
+ }
+ if (data.framework.version) {
+ if (!positionData.framework.version) {
+ addInsert(["framework", "version"], data.framework.version);
+ } else if (getValue(positionData.framework.version) !== data.framework.version) {
+ addUpdate(["framework", "version"], data.framework.version);
+ }
+ }
+ if (data.framework.libraries) {
+ if (!positionData.framework.libraries) {
+ addInsert(["framework", "libraries"], data.framework.libraries);
+ } else if (Array.isArray(data.framework.libraries) && data.framework.libraries.length > 0) {
+ addUpdate(["framework", "libraries"], data.framework.libraries);
+ } else {
+ // remove empty array
+ addRemove(["framework", "libraries"]);
+ }
+ }
+ }
+
+ // TODO: detect windows line-endings
+ if (!projectDocumentContent.endsWith("\n")) {
+ projectDocumentContent += "\n";
+ }
+
+ const adoptedProjectYaml = applyChanges(projectDocumentContent, changes);
+
+ const array = Array.from(configFile);
+ array.splice(projectDocumentStartIndex, projectDocumentContent.length, adoptedProjectYaml);
+ let adoptedYaml = array.join("");
+
+ // TODO: detect windows line-endings
+ if (!adoptedYaml.endsWith("\n")) {
+ adoptedYaml += "\n";
+ }
+
+ // Validate content before writing
+ try {
+ loadAll(adoptedYaml);
+ } catch (err) {
+ const error = new Error("Failed to update YAML file: " + err.message);
+ error.name = "FrameworkUpdateYamlFailed";
+ log.verbose(error.message);
+ log.verbose(`Original YAML (${configPath}):\n` + configFile);
+ log.verbose("Updated YAML:\n" + adoptedYaml);
+ throw error;
+ }
+
+ await writeFile(configPath, adoptedYaml);
+}
diff --git a/packages/cli/lib/framework/use.js b/packages/cli/lib/framework/use.js
new file mode 100644
index 00000000000..dac068dda5b
--- /dev/null
+++ b/packages/cli/lib/framework/use.js
@@ -0,0 +1,67 @@
+import {getRootProjectConfiguration, frameworkResolverResolveVersion} from "./utils.js";
+
+function getEffectiveFrameworkName({project, frameworkOptions}) {
+ if (!project.getFrameworkName() && !frameworkOptions.name) {
+ throw new Error("No framework configuration defined. Make sure to also provide the framework name.");
+ }
+
+ if (frameworkOptions.name) {
+ if (frameworkOptions.name.toLowerCase() === "openui5") {
+ return "OpenUI5";
+ } else if (frameworkOptions.name.toLowerCase() === "sapui5") {
+ return "SAPUI5";
+ } else {
+ throw new Error("Invalid framework name: " + frameworkOptions.name);
+ }
+ } else {
+ return project.getFrameworkName();
+ }
+}
+
+export default async function({projectGraphOptions, frameworkOptions}) {
+ const project = await getRootProjectConfiguration(projectGraphOptions);
+
+ if (project.getSpecVersion().lt("2.0")) {
+ throw new Error(
+ `ui5 use command requires specVersion "2.0" or higher. ` +
+ `Project ${project.getName()} uses specVersion "${project.getSpecVersion().toString()}"`
+ );
+ }
+
+ const framework = {
+ name: getEffectiveFrameworkName({project, frameworkOptions})
+ };
+
+ const frameworkVersion = frameworkOptions.version || project.getFrameworkVersion();
+ if (frameworkVersion) {
+ framework.version = await frameworkResolverResolveVersion({
+ frameworkName: framework.name,
+ frameworkVersion
+ }, {
+ cwd: project.getRootPath()
+ });
+ }
+
+ // Try to update YAML file but still return with name and resolved version in case it failed
+ let yamlUpdated = false;
+ try {
+ const {default: updateYaml} = await import("./updateYaml.js");
+ await updateYaml({
+ project,
+ configPathOverride: projectGraphOptions.config,
+ data: {
+ framework: framework
+ }
+ });
+ yamlUpdated = true;
+ } catch (err) {
+ if (err.name !== "FrameworkUpdateYamlFailed") {
+ throw err;
+ }
+ }
+ return {
+ yamlUpdated,
+ usedFramework: framework.name,
+ usedVersion: framework.version || null
+ };
+}
diff --git a/packages/cli/lib/framework/utils.js b/packages/cli/lib/framework/utils.js
new file mode 100644
index 00000000000..799c8a35253
--- /dev/null
+++ b/packages/cli/lib/framework/utils.js
@@ -0,0 +1,75 @@
+import path from "node:path";
+import {graphFromStaticFile, graphFromPackageDependencies} from "@ui5/project/graph";
+import Configuration from "@ui5/project/config/Configuration";
+
+export async function getRootProjectConfiguration(projectGraphOptions) {
+ let graph;
+ if (projectGraphOptions.dependencyDefinition) {
+ graph = await graphFromStaticFile({
+ filePath: projectGraphOptions.dependencyDefinition,
+ resolveFrameworkDependencies: false
+ });
+ } else {
+ graph = await graphFromPackageDependencies({
+ rootConfigPath: projectGraphOptions.config,
+ resolveFrameworkDependencies: false
+ });
+ }
+
+ return graph.getRoot();
+}
+
+async function getFrameworkResolver(frameworkName, frameworkVersion) {
+ if (frameworkVersion.toLowerCase().endsWith("-snapshot")) {
+ // Framework version could be for example: "latest-snapshot" or "1.112.0-SNAPSHOT"
+ return (await import("@ui5/project/ui5Framework/Sapui5MavenSnapshotResolver")).default;
+ } else if (frameworkName === "OpenUI5") {
+ return (await import("@ui5/project/ui5Framework/Openui5Resolver")).default;
+ } else if (frameworkName === "SAPUI5") {
+ return (await import("@ui5/project/ui5Framework/Sapui5Resolver")).default;
+ } else {
+ throw new Error("Invalid framework.name: " + frameworkName);
+ }
+}
+
+export async function createFrameworkResolverInstance({frameworkName, frameworkVersion}, {cwd}) {
+ const Resolver = await utils.getFrameworkResolver(frameworkName, frameworkVersion);
+ return new Resolver({
+ cwd,
+ version: frameworkVersion,
+ ui5DataDir: await utils.getUi5DataDir({cwd})
+ });
+}
+
+export async function frameworkResolverResolveVersion({frameworkName, frameworkVersion}, {cwd}) {
+ const Resolver = await utils.getFrameworkResolver(frameworkName, frameworkVersion);
+ return Resolver.resolveVersion(frameworkVersion, {
+ cwd,
+ ui5DataDir: await utils.getUi5DataDir({cwd})
+ });
+}
+
+async function getUi5DataDir({cwd}) {
+ // ENV var should take precedence over the dataDir from the configuration.
+ let ui5DataDir = process.env.UI5_DATA_DIR;
+ if (!ui5DataDir) {
+ const config = await Configuration.fromFile();
+ ui5DataDir = config.getUi5DataDir();
+ }
+ return ui5DataDir ? path.resolve(cwd, ui5DataDir) : undefined;
+}
+
+const utils = {
+ getRootProjectConfiguration,
+ getFrameworkResolver,
+ createFrameworkResolverInstance,
+ frameworkResolverResolveVersion,
+ getUi5DataDir
+};
+let _utils;
+// For mocking of functions in unit tests and testing internal functions
+/* istanbul ignore else */
+if (process.env.NODE_ENV === "test") {
+ _utils = utils;
+}
+export {_utils};
diff --git a/packages/cli/lib/init/init.js b/packages/cli/lib/init/init.js
new file mode 100644
index 00000000000..3ad20b2fad9
--- /dev/null
+++ b/packages/cli/lib/init/init.js
@@ -0,0 +1,102 @@
+import path from "node:path";
+import {readFile} from "node:fs/promises";
+import {pathsExist} from "../utils/fsHelper.js";
+
+/**
+ * Reads the package.json file and returns its content
+ *
+ * @private
+ * @param {string} filePath Path to package.json
+ * @returns {object} Package json content
+ */
+async function readPackageJson(filePath) {
+ const content = await readFile(filePath, "utf8");
+ return JSON.parse(content);
+}
+
+/**
+ * Determines the project type from the provided parameters
+ *
+ * @private
+ * @param {boolean} hasWebapp Webapp folder exists
+ * @param {boolean} hasSrc Src folder exists
+ * @param {boolean} hasTest Test folder exists
+ * @returns {string} Project type
+ */
+function getProjectType(hasWebapp, hasSrc, hasTest) {
+ let errorReason;
+ if (hasWebapp) {
+ // Mixed folders of application and library
+ if (hasSrc && hasTest) {
+ errorReason = "Found 'webapp', 'src' and 'test' folders.\n";
+ } else if (hasSrc) {
+ errorReason = "Found 'webapp' and 'src' folders.\n";
+ } else if (hasTest) {
+ errorReason = "Found 'webapp' and 'test' folders.\n";
+ } else {
+ return "application";
+ }
+ } else if (hasSrc) {
+ return "library";
+ } else if (hasTest) {
+ // Only test folder
+ errorReason = "Found 'test' folder but no 'src' folder.\n";
+ } else {
+ // No folders at all
+ errorReason = "Could not find 'webapp' or 'src' / 'test' folders.\n";
+ }
+
+ let message = `Could not detect project type: ${errorReason}`;
+ message += "Applications should only have a 'webapp' folder.\n";
+ message += "Libraries should only have an 'src' and (optional) 'test' folder.";
+ message += "\n\n";
+ message += "If you are about to start a new project, please refer to:\n";
+ message += "https://ui5.github.io/cli/v4/pages/GettingStarted/#starting-a-new-project";
+ throw new Error(message);
+}
+
+/**
+ * @module @ui5/cli/init
+ */
+
+/**
+ * Initiates the projects ui5.yaml configuration file.
+ *
+ * Checks the package.json and tries to determine the project type. If the ui5.yaml file does not exist,
+ * it is created with the basic project configuration.
+ *
+ * @function default
+ * @static
+ * @param {string} cwd Current working directory
+ * @returns {Promise} Promise resolving with the project configuration object
+ */
+async function init({cwd = "./"} = {}) {
+ const projectConfig = {
+ specVersion: "4.0",
+ metadata: {}
+ };
+ let pkg;
+
+ try {
+ pkg = await readPackageJson(path.join(cwd, "package.json"));
+ } catch (err) {
+ if (err.code === "ENOENT") {
+ throw new Error("Initialization not possible: Missing package.json file");
+ } else {
+ throw err;
+ }
+ }
+
+ if (pkg && pkg.name) {
+ projectConfig.metadata.name = pkg.name;
+ } else {
+ throw new Error("Initialization not possible: Missing 'name' in package.json");
+ }
+
+ const [hasWebapp, hasSrc, hasTest] = await pathsExist(["webapp", "src", "test"], cwd);
+ projectConfig.type = getProjectType(hasWebapp, hasSrc, hasTest);
+
+ return projectConfig;
+}
+
+export default init;
diff --git a/packages/cli/lib/utils/fsHelper.js b/packages/cli/lib/utils/fsHelper.js
new file mode 100644
index 00000000000..ebaf500117f
--- /dev/null
+++ b/packages/cli/lib/utils/fsHelper.js
@@ -0,0 +1,35 @@
+import {stat} from "node:fs/promises";
+import path from "node:path";
+
+/**
+ * Checks if a file or path exists
+ *
+ * @private
+ * @param {string} filePath Path to check
+ * @returns {Promise} Promise resolving with true if the file or path exists
+ */
+export async function exists(filePath) {
+ try {
+ await stat(filePath);
+ return true;
+ } catch (err) {
+ // "File or directory does not exist"
+ if (err.code === "ENOENT") {
+ return false;
+ } else {
+ throw err;
+ }
+ }
+}
+
+/**
+ * Checks if a list of paths exists
+ *
+ * @private
+ * @param {Array} paths List of paths to check
+ * @param {string} cwd Current working directory
+ * @returns {Promise} Resolving with an array of booleans for each path
+ */
+export async function pathsExist(paths, cwd) {
+ return await Promise.all(paths.map((p) => exists(path.join(cwd, p))));
+}
diff --git a/packages/cli/npm-shrinkwrap.json b/packages/cli/npm-shrinkwrap.json
new file mode 100644
index 00000000000..2bd17e6ec8d
--- /dev/null
+++ b/packages/cli/npm-shrinkwrap.json
@@ -0,0 +1,13139 @@
+{
+ "name": "@ui5/cli",
+ "version": "4.0.26",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@ui5/cli",
+ "version": "4.0.26",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ui5/builder": "^4.0.11",
+ "@ui5/fs": "^4.0.2",
+ "@ui5/logger": "^4.0.2",
+ "@ui5/project": "^4.0.6",
+ "@ui5/server": "^4.0.7",
+ "chalk": "^5.6.2",
+ "data-with-position": "^0.5.0",
+ "import-local": "^3.2.0",
+ "js-yaml": "^4.1.0",
+ "open": "^10.2.0",
+ "pretty-hrtime": "^1.0.3",
+ "semver": "^7.7.2",
+ "update-notifier": "^7.3.1",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "ui5": "bin/ui5.cjs"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.8.0",
+ "@istanbuljs/esm-loader-hook": "^0.3.0",
+ "ava": "^6.4.1",
+ "chokidar-cli": "^3.0.0",
+ "cross-env": "^7.0.3",
+ "depcheck": "^1.4.7",
+ "docdash": "^2.0.2",
+ "eslint": "^9.36.0",
+ "eslint-config-google": "^0.14.0",
+ "eslint-plugin-ava": "^15.1.0",
+ "eslint-plugin-jsdoc": "^52.0.4",
+ "esmock": "^2.7.3",
+ "execa": "^9.6.0",
+ "globals": "^16.4.0",
+ "jsdoc": "^4.0.4",
+ "licensee": "^11.1.1",
+ "nyc": "^17.1.0",
+ "open-cli": "^8.0.0",
+ "rimraf": "^6.0.1",
+ "sinon": "^21.0.0",
+ "strip-ansi": "^7.1.2",
+ "tap-xunit": "^2.4.1",
+ "testdouble": "^3.20.2"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ }
+ },
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
+ "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz",
+ "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz",
+ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.3",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.4",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.4",
+ "@babel/types": "^7.28.4",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
+ "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "@babel/types": "^7.28.2",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.27.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.27.2",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz",
+ "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-member-expression-to-functions": "^7.27.1",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/traverse": "^7.28.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz",
+ "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.28.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz",
+ "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.27.1",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
+ "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
+ "dependencies": {
+ "@babel/types": "^7.28.4"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-decorators": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz",
+ "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz",
+ "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz",
+ "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz",
+ "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz",
+ "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-typescript": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz",
+ "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+ "@babel/plugin-transform-typescript": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz",
+ "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.3",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.4",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
+ "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@blueoak/list": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/@blueoak/list/-/list-15.0.0.tgz",
+ "integrity": "sha512-xW5Xb9Fr3WtYAOwavxxWL0CaJK/ReT+HKb5/R6dR1p9RVJ55MTdaxPdeTKY2ukhFchv2YHPMM8YuZyfyLqxedg==",
+ "dev": true
+ },
+ "node_modules/@es-joy/jsdoccomment": {
+ "version": "0.52.0",
+ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.52.0.tgz",
+ "integrity": "sha512-BXuN7BII+8AyNtn57euU2Yxo9yA/KUDNzrpXyi3pfqKmBhhysR6ZWOebFh3vyPoqA3/j1SOvGgucElMGwlXing==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.8",
+ "@typescript-eslint/types": "^8.34.1",
+ "comment-parser": "1.4.1",
+ "esquery": "^1.6.0",
+ "jsdoc-type-pratt-parser": "~4.1.0"
+ },
+ "engines": {
+ "node": ">=20.11.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz",
+ "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/core": "^0.15.2",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@isaacs/balanced-match": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
+ "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/brace-expansion": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
+ "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
+ "dependencies": {
+ "@isaacs/balanced-match": "^4.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/fs-minipass": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+ "dependencies": {
+ "minipass": "^7.0.4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@isaacs/string-locale-compare": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz",
+ "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==",
+ "dev": true
+ },
+ "node_modules/@istanbuljs/esm-loader-hook": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/esm-loader-hook/-/esm-loader-hook-0.3.0.tgz",
+ "integrity": "sha512-lEnYroBUYfNQuJDYrPvre8TSwPZnyIQv9qUT3gACvhr3igZr+BbrdyIcz4+2RnEXZzi12GqkUW600+QQPpIbVg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.8.7",
+ "@babel/plugin-syntax-decorators": "^7.25.9",
+ "@babel/preset-typescript": "^7.26.0",
+ "@istanbuljs/load-nyc-config": "^1.1.0",
+ "@istanbuljs/schema": "^0.1.3",
+ "babel-plugin-istanbul": "^6.0.0",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=16.12.0"
+ }
+ },
+ "node_modules/@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,
+ "dependencies": {
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@jsdoc/salty": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.9.tgz",
+ "integrity": "sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==",
+ "dependencies": {
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=v12.0.0"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz",
+ "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==",
+ "dev": true,
+ "dependencies": {
+ "consola": "^3.2.3",
+ "detect-libc": "^2.0.0",
+ "https-proxy-agent": "^7.0.5",
+ "node-fetch": "^2.6.7",
+ "nopt": "^8.0.0",
+ "semver": "^7.5.3",
+ "tar": "^7.4.0"
+ },
+ "bin": {
+ "node-pre-gyp": "bin/node-pre-gyp"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz",
+ "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/agent/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/@npmcli/arborist": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-7.5.4.tgz",
+ "integrity": "sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==",
+ "dev": true,
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/fs": "^3.1.1",
+ "@npmcli/installed-package-contents": "^2.1.0",
+ "@npmcli/map-workspaces": "^3.0.2",
+ "@npmcli/metavuln-calculator": "^7.1.1",
+ "@npmcli/name-from-folder": "^2.0.0",
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.1.0",
+ "@npmcli/query": "^3.1.0",
+ "@npmcli/redact": "^2.0.0",
+ "@npmcli/run-script": "^8.1.0",
+ "bin-links": "^4.0.4",
+ "cacache": "^18.0.3",
+ "common-ancestor-path": "^1.0.1",
+ "hosted-git-info": "^7.0.2",
+ "json-parse-even-better-errors": "^3.0.2",
+ "json-stringify-nice": "^1.1.4",
+ "lru-cache": "^10.2.2",
+ "minimatch": "^9.0.4",
+ "nopt": "^7.2.1",
+ "npm-install-checks": "^6.2.0",
+ "npm-package-arg": "^11.0.2",
+ "npm-pick-manifest": "^9.0.1",
+ "npm-registry-fetch": "^17.0.1",
+ "pacote": "^18.0.6",
+ "parse-conflict-json": "^3.0.0",
+ "proc-log": "^4.2.0",
+ "proggy": "^2.0.0",
+ "promise-all-reject-late": "^1.0.0",
+ "promise-call-limit": "^3.0.1",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "ssri": "^10.0.6",
+ "treeverse": "^3.0.0",
+ "walk-up-path": "^3.0.1"
+ },
+ "bin": {
+ "arborist": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@npmcli/agent": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
+ "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@npmcli/git": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz",
+ "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/promise-spawn": "^7.0.0",
+ "ini": "^4.1.3",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "proc-log": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@npmcli/map-workspaces": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz",
+ "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/name-from-folder": "^2.0.0",
+ "glob": "^10.2.2",
+ "minimatch": "^9.0.0",
+ "read-package-json-fast": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@npmcli/name-from-folder": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz",
+ "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@npmcli/package-json": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz",
+ "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^7.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@npmcli/promise-spawn": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz",
+ "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==",
+ "dev": true,
+ "dependencies": {
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@sigstore/bundle": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz",
+ "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.2"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@sigstore/core": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz",
+ "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==",
+ "dev": true,
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@sigstore/protobuf-specs": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.3.tgz",
+ "integrity": "sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@sigstore/sign": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz",
+ "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.2",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.2",
+ "make-fetch-happen": "^13.0.1",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@sigstore/tuf": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz",
+ "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.2",
+ "tuf-js": "^2.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@sigstore/verify": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz",
+ "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.2",
+ "@sigstore/core": "^1.1.0",
+ "@sigstore/protobuf-specs": "^0.3.2"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/@tufjs/models": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz",
+ "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==",
+ "dev": true,
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/abbrev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/ignore-walk": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz",
+ "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==",
+ "dev": true,
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/ini": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz",
+ "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/@npmcli/arborist/node_modules/make-fetch-happen": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
+ "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/minipass-fetch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
+ "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/nopt": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/npm-packlist": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz",
+ "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==",
+ "dev": true,
+ "dependencies": {
+ "ignore-walk": "^6.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/npm-pick-manifest": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz",
+ "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==",
+ "dev": true,
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^11.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/pacote": {
+ "version": "18.0.6",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz",
+ "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "@npmcli/installed-package-contents": "^2.0.1",
+ "@npmcli/package-json": "^5.1.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "@npmcli/run-script": "^8.0.0",
+ "cacache": "^18.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^11.0.0",
+ "npm-packlist": "^8.0.0",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^17.0.0",
+ "proc-log": "^4.0.0",
+ "promise-retry": "^2.0.1",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/sigstore": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz",
+ "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.2",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.2",
+ "@sigstore/sign": "^2.3.2",
+ "@sigstore/tuf": "^2.3.4",
+ "@sigstore/verify": "^1.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/tuf-js": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz",
+ "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==",
+ "dev": true,
+ "dependencies": {
+ "@tufjs/models": "2.0.1",
+ "debug": "^4.3.4",
+ "make-fetch-happen": "^13.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/arborist/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/@npmcli/config": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-9.0.0.tgz",
+ "integrity": "sha512-P5Vi16Y+c8E0prGIzX112ug7XxqfaPFUVW/oXAV+2VsxplKZEnJozqZ0xnK8V8w/SEsBf+TXhUihrEIAU4CA5Q==",
+ "dependencies": {
+ "@npmcli/map-workspaces": "^4.0.1",
+ "@npmcli/package-json": "^6.0.1",
+ "ci-info": "^4.0.0",
+ "ini": "^5.0.0",
+ "nopt": "^8.0.0",
+ "proc-log": "^5.0.0",
+ "semver": "^7.3.5",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/fs": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
+ "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/git": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz",
+ "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==",
+ "dependencies": {
+ "@npmcli/promise-spawn": "^8.0.0",
+ "ini": "^5.0.0",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^10.0.0",
+ "proc-log": "^5.0.0",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/git/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/@npmcli/installed-package-contents": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz",
+ "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==",
+ "dev": true,
+ "dependencies": {
+ "npm-bundled": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "bin": {
+ "installed-package-contents": "bin/index.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/map-workspaces": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-4.0.2.tgz",
+ "integrity": "sha512-mnuMuibEbkaBTYj9HQ3dMe6L0ylYW+s/gfz7tBDMFY/la0w9Kf44P9aLn4/+/t3aTR3YUHKoT6XQL9rlicIe3Q==",
+ "dependencies": {
+ "@npmcli/name-from-folder": "^3.0.0",
+ "@npmcli/package-json": "^6.0.0",
+ "glob": "^10.2.2",
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@npmcli/map-workspaces/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-7.1.1.tgz",
+ "integrity": "sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==",
+ "dev": true,
+ "dependencies": {
+ "cacache": "^18.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "pacote": "^18.0.0",
+ "proc-log": "^4.1.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@npmcli/agent": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
+ "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@npmcli/git": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz",
+ "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/promise-spawn": "^7.0.0",
+ "ini": "^4.1.3",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "proc-log": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@npmcli/package-json": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz",
+ "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^7.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@npmcli/promise-spawn": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz",
+ "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==",
+ "dev": true,
+ "dependencies": {
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@sigstore/bundle": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz",
+ "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.2"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@sigstore/core": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz",
+ "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==",
+ "dev": true,
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@sigstore/protobuf-specs": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.3.tgz",
+ "integrity": "sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@sigstore/sign": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz",
+ "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.2",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.2",
+ "make-fetch-happen": "^13.0.1",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@sigstore/tuf": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz",
+ "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.2",
+ "tuf-js": "^2.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@sigstore/verify": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz",
+ "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.2",
+ "@sigstore/core": "^1.1.0",
+ "@sigstore/protobuf-specs": "^0.3.2"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/@tufjs/models": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz",
+ "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==",
+ "dev": true,
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/ignore-walk": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz",
+ "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==",
+ "dev": true,
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/ini": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz",
+ "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/make-fetch-happen": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
+ "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/minipass-fetch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
+ "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/npm-packlist": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz",
+ "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==",
+ "dev": true,
+ "dependencies": {
+ "ignore-walk": "^6.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/npm-pick-manifest": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz",
+ "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==",
+ "dev": true,
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^11.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/pacote": {
+ "version": "18.0.6",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz",
+ "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "@npmcli/installed-package-contents": "^2.0.1",
+ "@npmcli/package-json": "^5.1.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "@npmcli/run-script": "^8.0.0",
+ "cacache": "^18.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^11.0.0",
+ "npm-packlist": "^8.0.0",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^17.0.0",
+ "proc-log": "^4.0.0",
+ "promise-retry": "^2.0.1",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/sigstore": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz",
+ "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.2",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.2",
+ "@sigstore/sign": "^2.3.2",
+ "@sigstore/tuf": "^2.3.4",
+ "@sigstore/verify": "^1.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/tuf-js": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz",
+ "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==",
+ "dev": true,
+ "dependencies": {
+ "@tufjs/models": "2.0.1",
+ "debug": "^4.3.4",
+ "make-fetch-happen": "^13.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/metavuln-calculator/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/@npmcli/name-from-folder": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-3.0.0.tgz",
+ "integrity": "sha512-61cDL8LUc9y80fXn+lir+iVt8IS0xHqEKwPu/5jCjxQTVoSCmkXvw4vbMrzAMtmghz3/AkiBjhHkDKUH+kf7kA==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/node-gyp": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz",
+ "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/package-json": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz",
+ "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==",
+ "dependencies": {
+ "@npmcli/git": "^6.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^8.0.0",
+ "json-parse-even-better-errors": "^4.0.0",
+ "proc-log": "^5.0.0",
+ "semver": "^7.5.3",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/promise-spawn": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.3.tgz",
+ "integrity": "sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==",
+ "dependencies": {
+ "which": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/query": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-3.1.0.tgz",
+ "integrity": "sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/redact": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz",
+ "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==",
+ "dev": true,
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz",
+ "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "node-gyp": "^10.0.0",
+ "proc-log": "^4.0.0",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/@npmcli/git": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz",
+ "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/promise-spawn": "^7.0.0",
+ "ini": "^4.1.3",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "proc-log": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/@npmcli/package-json": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz",
+ "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^7.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/@npmcli/promise-spawn": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz",
+ "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==",
+ "dev": true,
+ "dependencies": {
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/ini": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz",
+ "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/@npmcli/run-script/node_modules/npm-pick-manifest": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz",
+ "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==",
+ "dev": true,
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^11.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pnpm/config.env-replace": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
+ "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
+ "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
+ "dependencies": {
+ "graceful-fs": "4.2.10"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "node_modules/@pnpm/npm-conf": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz",
+ "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==",
+ "dependencies": {
+ "@pnpm/config.env-replace": "^1.1.0",
+ "@pnpm/network.ca-file": "^1.0.1",
+ "config-chain": "^1.1.11"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
+ "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@sec-ant/readable-stream": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
+ "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
+ "dev": true
+ },
+ "node_modules/@sigstore/bundle": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz",
+ "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.4.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@sigstore/core": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz",
+ "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@sigstore/protobuf-specs": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz",
+ "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@sigstore/sign": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz",
+ "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==",
+ "dependencies": {
+ "@sigstore/bundle": "^3.1.0",
+ "@sigstore/core": "^2.0.0",
+ "@sigstore/protobuf-specs": "^0.4.0",
+ "make-fetch-happen": "^14.0.2",
+ "proc-log": "^5.0.0",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@sigstore/tuf": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz",
+ "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.4.1",
+ "tuf-js": "^3.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@sigstore/verify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz",
+ "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==",
+ "dependencies": {
+ "@sigstore/bundle": "^3.1.0",
+ "@sigstore/core": "^2.0.0",
+ "@sigstore/protobuf-specs": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
+ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "13.0.5",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+ "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz",
+ "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "type-detect": "^4.1.0"
+ }
+ },
+ "node_modules/@sinonjs/samsam/node_modules/type-detect": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@tokenizer/token": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
+ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
+ "dev": true
+ },
+ "node_modules/@tufjs/canonical-json": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz",
+ "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@tufjs/models": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz",
+ "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==",
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^9.0.5"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@tufjs/models/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@tufjs/models/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="
+ },
+ "node_modules/@types/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
+ "dev": true
+ },
+ "node_modules/@types/normalize-package-data": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="
+ },
+ "node_modules/@types/parse-json": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
+ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.44.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz",
+ "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ui5/builder": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/@ui5/builder/-/builder-4.0.11.tgz",
+ "integrity": "sha512-6CsTCau0aP2NaXk9cZZ5dyINgKAoHL/n6l/O+d9ZTeHAKEyPM2+7WXXCLlMO/Z/SD+eEShztnsg1aCKyAzS5dQ==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5",
+ "@ui5/fs": "^4.0.2",
+ "@ui5/logger": "^4.0.2",
+ "cheerio": "1.0.0",
+ "escape-unicode": "^0.2.0",
+ "escope": "^4.0.0",
+ "espree": "^10.4.0",
+ "graceful-fs": "^4.2.11",
+ "jsdoc": "^4.0.4",
+ "less-openui5": "^0.11.6",
+ "pretty-data": "^0.40.0",
+ "semver": "^7.7.2",
+ "terser": "^5.44.0",
+ "workerpool": "^9.3.4",
+ "xml2js": "^0.6.2"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ }
+ },
+ "node_modules/@ui5/fs": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@ui5/fs/-/fs-4.0.2.tgz",
+ "integrity": "sha512-0R7eb9xEMswvkN2wIiyYJtQY83evQJ7LQhTnRf5Ms0o2R29twGLP4XewqH+IoGWyT3T4SuDNTWmUU2UaTRY4zg==",
+ "dependencies": {
+ "@ui5/logger": "^4.0.1",
+ "clone": "^2.1.2",
+ "escape-string-regexp": "^5.0.0",
+ "globby": "^14.1.0",
+ "graceful-fs": "^4.2.11",
+ "micromatch": "^4.0.8",
+ "minimatch": "^10.0.3",
+ "pretty-hrtime": "^1.0.3",
+ "random-int": "^3.0.0"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ }
+ },
+ "node_modules/@ui5/logger": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@ui5/logger/-/logger-4.0.2.tgz",
+ "integrity": "sha512-uscDCQyHFeenh4r2RbYuffTMn6IQdcNC1tXrQ4BF+apAFjmDGP11IHdAwVCKwxgyPrIC17HT2gub3ZugGM8kpQ==",
+ "dependencies": {
+ "chalk": "^5.6.0",
+ "cli-progress": "^3.12.0",
+ "figures": "^6.1.0"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ }
+ },
+ "node_modules/@ui5/project": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@ui5/project/-/project-4.0.6.tgz",
+ "integrity": "sha512-ryopHahdKxU9GXXfEf3RNQxodHOOdqUmzrQ1uymoa3Om83BMBcURs3FQERjOP4soDbM5RiI7wEdaXX9VRvgH4w==",
+ "dependencies": {
+ "@npmcli/config": "^9.0.0",
+ "@ui5/fs": "^4.0.2",
+ "@ui5/logger": "^4.0.2",
+ "ajv": "^6.12.6",
+ "ajv-errors": "^1.0.1",
+ "chalk": "^5.6.2",
+ "escape-string-regexp": "^5.0.0",
+ "globby": "^14.1.0",
+ "graceful-fs": "^4.2.11",
+ "js-yaml": "^4.1.0",
+ "lockfile": "^1.0.4",
+ "make-fetch-happen": "^14.0.3",
+ "node-stream-zip": "^1.15.0",
+ "pacote": "^19.0.1",
+ "pretty-hrtime": "^1.0.3",
+ "read-package-up": "^11.0.0",
+ "read-pkg": "^9.0.1",
+ "resolve": "^1.22.10",
+ "semver": "^7.7.2",
+ "xml2js": "^0.6.2",
+ "yesno": "^0.4.0"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ },
+ "peerDependencies": {
+ "@ui5/builder": "^4.0.11"
+ },
+ "peerDependenciesMeta": {
+ "@ui5/builder": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@ui5/server": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@ui5/server/-/server-4.0.7.tgz",
+ "integrity": "sha512-bc6w/ispz8A1gnTFj3SqmA16geY6gMX8sP53enbq3YAf2HW7q5/E0/rdWj2BWlWQLW1zW/zVWCPAi6PX7lYJqQ==",
+ "dependencies": {
+ "@ui5/builder": "^4.0.11",
+ "@ui5/fs": "^4.0.2",
+ "@ui5/logger": "^4.0.2",
+ "body-parser": "^1.20.2",
+ "compression": "^1.8.1",
+ "cors": "^2.8.5",
+ "devcert-sanscache": "^0.5.1",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "express": "^4.21.2",
+ "fresh": "^0.5.2",
+ "graceful-fs": "^4.2.11",
+ "mime-types": "^2.1.35",
+ "parseurl": "^1.3.3",
+ "portscanner": "^2.2.0",
+ "replacestream": "^4.0.3",
+ "router": "^2.2.0",
+ "spdy": "^4.0.2",
+ "yesno": "^0.4.0"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ }
+ },
+ "node_modules/@vercel/nft": {
+ "version": "0.29.4",
+ "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.29.4.tgz",
+ "integrity": "sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==",
+ "dev": true,
+ "dependencies": {
+ "@mapbox/node-pre-gyp": "^2.0.0",
+ "@rollup/pluginutils": "^5.1.3",
+ "acorn": "^8.6.0",
+ "acorn-import-attributes": "^1.9.5",
+ "async-sema": "^3.1.1",
+ "bindings": "^1.4.0",
+ "estree-walker": "2.0.2",
+ "glob": "^10.4.5",
+ "graceful-fs": "^4.2.9",
+ "node-gyp-build": "^4.2.2",
+ "picomatch": "^4.0.2",
+ "resolve-from": "^5.0.0"
+ },
+ "bin": {
+ "nft": "out/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.21.tgz",
+ "integrity": "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "@vue/shared": "3.5.21",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.21.tgz",
+ "integrity": "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==",
+ "dev": true,
+ "dependencies": {
+ "@vue/compiler-core": "3.5.21",
+ "@vue/shared": "3.5.21"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.21.tgz",
+ "integrity": "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "@vue/compiler-core": "3.5.21",
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/compiler-ssr": "3.5.21",
+ "@vue/shared": "3.5.21",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.18",
+ "postcss": "^8.5.6",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.21.tgz",
+ "integrity": "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==",
+ "dev": true,
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/shared": "3.5.21"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.21.tgz",
+ "integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==",
+ "dev": true
+ },
+ "node_modules/abbrev": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz",
+ "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "dev": true,
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6.5"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/accepts/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-attributes": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
+ "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/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,
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/aggregate-error/node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-errors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+ "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+ "peerDependencies": {
+ "ajv": ">=5.0.0"
+ }
+ },
+ "node_modules/ansi-align": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
+ "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
+ "dependencies": {
+ "string-width": "^4.1.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/append-transform": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
+ "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
+ "dev": true,
+ "dependencies": {
+ "default-require-extensions": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
+ "dev": true
+ },
+ "node_modules/are-docs-informative": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+ "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "node_modules/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==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/arrgv": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz",
+ "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/arrify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz",
+ "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/async-sema": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz",
+ "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==",
+ "dev": true
+ },
+ "node_modules/atomically": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.0.3.tgz",
+ "integrity": "sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==",
+ "dependencies": {
+ "stubborn-fs": "^1.2.5",
+ "when-exit": "^2.1.1"
+ }
+ },
+ "node_modules/ava": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/ava/-/ava-6.4.1.tgz",
+ "integrity": "sha512-vxmPbi1gZx9zhAjHBgw81w/iEDKcrokeRk/fqDTyA2DQygZ0o+dUGRHFOtX8RA5N0heGJTTsIk7+xYxitDb61Q==",
+ "dev": true,
+ "dependencies": {
+ "@vercel/nft": "^0.29.4",
+ "acorn": "^8.15.0",
+ "acorn-walk": "^8.3.4",
+ "ansi-styles": "^6.2.1",
+ "arrgv": "^1.0.2",
+ "arrify": "^3.0.0",
+ "callsites": "^4.2.0",
+ "cbor": "^10.0.9",
+ "chalk": "^5.4.1",
+ "chunkd": "^2.0.1",
+ "ci-info": "^4.3.0",
+ "ci-parallel-vars": "^1.0.1",
+ "cli-truncate": "^4.0.0",
+ "code-excerpt": "^4.0.0",
+ "common-path-prefix": "^3.0.0",
+ "concordance": "^5.0.4",
+ "currently-unhandled": "^0.4.1",
+ "debug": "^4.4.1",
+ "emittery": "^1.2.0",
+ "figures": "^6.1.0",
+ "globby": "^14.1.0",
+ "ignore-by-default": "^2.1.0",
+ "indent-string": "^5.0.0",
+ "is-plain-object": "^5.0.0",
+ "is-promise": "^4.0.0",
+ "matcher": "^5.0.0",
+ "memoize": "^10.1.0",
+ "ms": "^2.1.3",
+ "p-map": "^7.0.3",
+ "package-config": "^5.0.0",
+ "picomatch": "^4.0.2",
+ "plur": "^5.1.0",
+ "pretty-ms": "^9.2.0",
+ "resolve-cwd": "^3.0.0",
+ "stack-utils": "^2.0.6",
+ "strip-ansi": "^7.1.0",
+ "supertap": "^3.0.1",
+ "temp-dir": "^3.0.0",
+ "write-file-atomic": "^6.0.0",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "ava": "entrypoints/cli.mjs"
+ },
+ "engines": {
+ "node": "^18.18 || ^20.8 || ^22 || ^23 || >=24"
+ },
+ "peerDependencies": {
+ "@ava/typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "@ava/typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz",
+ "integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==",
+ "dev": true,
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/bin-links": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz",
+ "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==",
+ "dev": true,
+ "dependencies": {
+ "cmd-shim": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "read-cmd-shim": "^4.0.0",
+ "write-file-atomic": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/bin-links/node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
+ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "dev": true,
+ "dependencies": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "node_modules/blueimp-md5": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
+ "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
+ "dev": true
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+ },
+ "node_modules/boxen": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz",
+ "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==",
+ "dependencies": {
+ "ansi-align": "^3.0.1",
+ "camelcase": "^8.0.0",
+ "chalk": "^5.3.0",
+ "cli-boxes": "^3.0.0",
+ "string-width": "^7.2.0",
+ "type-fest": "^4.21.0",
+ "widest-line": "^5.0.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/camelcase": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
+ "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/emoji-regex": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz",
+ "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg=="
+ },
+ "node_modules/boxen/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.26.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz",
+ "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "baseline-browser-mapping": "^2.8.3",
+ "caniuse-lite": "^1.0.30001741",
+ "electron-to-chromium": "^1.5.218",
+ "node-releases": "^2.0.21",
+ "update-browserslist-db": "^1.1.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ },
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cacache": {
+ "version": "18.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz",
+ "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cacache/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/cacache/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cacache/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacache/node_modules/p-map": {
+ "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,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cacache/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cacache/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cacache/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacache/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacache/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/caching-transform": {
+ "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,
+ "dependencies": {
+ "hasha": "^5.0.0",
+ "make-dir": "^3.0.0",
+ "package-hash": "^4.0.0",
+ "write-file-atomic": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/caching-transform/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/caching-transform/node_modules/write-file-atomic": {
+ "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,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+ "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz",
+ "integrity": "sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001743",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz",
+ "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/catharsis": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
+ "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
+ "dependencies": {
+ "lodash": "^4.17.15"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/cbor": {
+ "version": "10.0.11",
+ "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.11.tgz",
+ "integrity": "sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==",
+ "dev": true,
+ "dependencies": {
+ "nofilter": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+ "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "encoding-sniffer": "^0.2.0",
+ "htmlparser2": "^9.1.0",
+ "parse5": "^7.1.2",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^6.19.5",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18.17"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar-cli": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar-cli/-/chokidar-cli-3.0.0.tgz",
+ "integrity": "sha512-xVW+Qeh7z15uZRxHOkP93Ux8A0xbPzwK4GaqD8dQOYc34TlkqUhVSS59fK36DOp5WdJlrRzlYSy02Ht99FjZqQ==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "lodash.debounce": "^4.0.8",
+ "lodash.throttle": "^4.1.1",
+ "yargs": "^13.3.0"
+ },
+ "bin": {
+ "chokidar": "index.js"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
+ "node_modules/chokidar-cli/node_modules/yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "dependencies": {
+ "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"
+ }
+ },
+ "node_modules/chokidar-cli/node_modules/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,
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chunkd": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz",
+ "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==",
+ "dev": true
+ },
+ "node_modules/ci-info": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz",
+ "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ci-parallel-vars": {
+ "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
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-boxes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+ "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-progress": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz",
+ "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==",
+ "dependencies": {
+ "string-width": "^4.2.3"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/emoji-regex": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz",
+ "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==",
+ "dev": true
+ },
+ "node_modules/cli-truncate/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cliui/node_modules/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==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/cliui/node_modules/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=="
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/cmd-shim": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz",
+ "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/code-excerpt": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz",
+ "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==",
+ "dev": true,
+ "dependencies": {
+ "convert-to-spaces": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/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,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/command-exists": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
+ "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w=="
+ },
+ "node_modules/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=="
+ },
+ "node_modules/comment-parser": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+ "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ }
+ },
+ "node_modules/common-ancestor-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz",
+ "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==",
+ "dev": true
+ },
+ "node_modules/common-path-prefix": {
+ "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
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+ "dev": true
+ },
+ "node_modules/compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dependencies": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/compression": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
+ "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
+ "debug": "2.6.9",
+ "negotiator": "~0.6.4",
+ "on-headers": "~1.1.0",
+ "safe-buffer": "5.2.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/compression/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/compression/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/concordance": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz",
+ "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==",
+ "dev": true,
+ "dependencies": {
+ "date-time": "^3.1.0",
+ "esutils": "^2.0.3",
+ "fast-diff": "^1.2.0",
+ "js-string-escape": "^1.0.1",
+ "lodash": "^4.17.15",
+ "md5-hex": "^3.0.1",
+ "semver": "^7.3.2",
+ "well-known-symbols": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/config-chain/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "node_modules/configstore": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-7.1.0.tgz",
+ "integrity": "sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==",
+ "dependencies": {
+ "atomically": "^2.0.3",
+ "dot-prop": "^9.0.0",
+ "graceful-fs": "^4.2.11",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/convert-to-spaces": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz",
+ "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ },
+ "node_modules/correct-license-metadata": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/correct-license-metadata/-/correct-license-metadata-1.4.0.tgz",
+ "integrity": "sha512-nvbNpK/aYCbztZWGi9adIPqR+ZcQmZTWNT7eMYLvkaVGroN1nTHiVuuNPl7pK6ZNx1mvDztlRBJtfUdrVwKJ5A==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-validate": "^2.0.0"
+ }
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "dev": true,
+ "dependencies": {
+ "@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"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ },
+ "node_modules/cross-spawn/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz",
+ "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/crypto-random-string/node_modules/type-fest": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==",
+ "dev": true,
+ "dependencies": {
+ "array-find-index": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/data-with-position": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/data-with-position/-/data-with-position-0.5.0.tgz",
+ "integrity": "sha512-GhsgEIPWk7WCAisjwBkOjvPqpAlVUOSl1CTmy9KyhVMG1wxl29Zj5+J71WhQ/KgoJS/Psxq6Cnioz3xdBjeIWQ==",
+ "dependencies": {
+ "yaml-ast-parser": "^0.0.43"
+ }
+ },
+ "node_modules/date-time": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz",
+ "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==",
+ "dev": true,
+ "dependencies": {
+ "time-zone": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/default-browser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
+ "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
+ "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-require-extensions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz",
+ "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==",
+ "dev": true,
+ "dependencies": {
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/depcheck": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-1.4.7.tgz",
+ "integrity": "sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.23.0",
+ "@babel/traverse": "^7.23.2",
+ "@vue/compiler-sfc": "^3.3.4",
+ "callsite": "^1.0.0",
+ "camelcase": "^6.3.0",
+ "cosmiconfig": "^7.1.0",
+ "debug": "^4.3.4",
+ "deps-regex": "^0.2.0",
+ "findup-sync": "^5.0.0",
+ "ignore": "^5.2.4",
+ "is-core-module": "^2.12.0",
+ "js-yaml": "^3.14.1",
+ "json5": "^2.2.3",
+ "lodash": "^4.17.21",
+ "minimatch": "^7.4.6",
+ "multimatch": "^5.0.0",
+ "please-upgrade-node": "^3.2.0",
+ "readdirp": "^3.6.0",
+ "require-package-name": "^2.0.1",
+ "resolve": "^1.22.3",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.5.4",
+ "yargs": "^16.2.0"
+ },
+ "bin": {
+ "depcheck": "bin/depcheck.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/depcheck/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/depcheck/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/depcheck/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/depcheck/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/depcheck/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/depcheck/node_modules/cliui": {
+ "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,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/depcheck/node_modules/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,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/depcheck/node_modules/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
+ },
+ "node_modules/depcheck/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/depcheck/node_modules/minimatch": {
+ "version": "7.4.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
+ "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/depcheck/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/depcheck/node_modules/wrap-ansi": {
+ "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,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/depcheck/node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/depcheck/node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/deps-regex": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz",
+ "integrity": "sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==",
+ "dev": true
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz",
+ "integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
+ },
+ "node_modules/devcert-sanscache": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/devcert-sanscache/-/devcert-sanscache-0.5.1.tgz",
+ "integrity": "sha512-9ePmMvWItstun0c35V5WXUlNU4MCHtpXWxKUJcDiZvyKkcA3FxkL6PFHKqTd446mXMmvLpOGBxVD6GjBXeMA5A==",
+ "dependencies": {
+ "command-exists": "^1.2.9",
+ "get-port": "^6.1.2",
+ "glob": "^10.4.5",
+ "rimraf": "^5.0.9"
+ },
+ "engines": {
+ "node": "^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/devcert-sanscache/node_modules/rimraf": {
+ "version": "5.0.10",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
+ "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
+ "dependencies": {
+ "glob": "^10.3.7"
+ },
+ "bin": {
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/diff": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/docdash": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/docdash/-/docdash-2.0.2.tgz",
+ "integrity": "sha512-3SDDheh9ddrwjzf6dPFe1a16M6ftstqTNjik2+1fx46l24H9dD2osT2q9y+nBEC1wWz4GIqA48JmicOLQ0R8xA==",
+ "dev": true,
+ "dependencies": {
+ "@jsdoc/salty": "^0.2.1"
+ }
+ },
+ "node_modules/docopt": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz",
+ "integrity": "sha512-NqTbaYeE4gA/wU1hdKFdU+AFahpDOpgGLzHP42k6H6DKExJd0A55KEVWYhL9FEmHmgeLvEU2vuKXDuU+4yToOw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz",
+ "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==",
+ "dependencies": {
+ "type-fest": "^4.18.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/dot-prop/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.222",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.222.tgz",
+ "integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==",
+ "dev": true
+ },
+ "node_modules/emittery": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.2.0.tgz",
+ "integrity": "sha512-KxdRyyFcS85pH3dnU8Y5yFUm2YJdaHwcBZWrfG8o89ZY9a13/f9itbN+YG3ELbBo9Pg5zvIozstmuV8bX13q6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/encoding-sniffer/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/enhance-visitors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz",
+ "integrity": "sha512-+29eJLiUixTEDRaZ35Vu8jP3gPLNcQQkQkOQjLp2X+6cZGGPDD/uasbFzvLsJKnGZnvmyZ0srxudwOtskHeIDA==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.13.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-goat": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz",
+ "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/escape-unicode": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/escape-unicode/-/escape-unicode-0.2.0.tgz",
+ "integrity": "sha512-7jMQuKb8nm0h/9HYLfu4NCLFwoUsd5XO6OZ1z86PbKcMf8zDK1m7nFR0iA2CCShq4TSValaLIveE8T1UBxgALQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/escope": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-4.0.0.tgz",
+ "integrity": "sha512-E36qlD/r6RJHVpPKArgMoMlNJzoRJFH8z/cAZlI9lbc45zB3+S7i9k6e/MNb+7bZQzNEa6r8WKN3BovpeIBwgA==",
+ "dependencies": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz",
+ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.36.0",
+ "@eslint/plugin-kit": "^0.3.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-google": {
+ "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,
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.16.0"
+ }
+ },
+ "node_modules/eslint-plugin-ava": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-15.1.0.tgz",
+ "integrity": "sha512-+6Zxk1uYW3mf7lxCLWIQsFYgn3hfuCMbsKc0MtqfloOz1F6fiV5/PaWEaLgkL1egrSQmnyR7vOFP1wSPJbVUbw==",
+ "dev": true,
+ "dependencies": {
+ "enhance-visitors": "^1.0.0",
+ "eslint-utils": "^3.0.0",
+ "espree": "^9.0.0",
+ "espurify": "^2.1.1",
+ "import-modules": "^2.1.0",
+ "micro-spelling-correcter": "^1.1.1",
+ "pkg-dir": "^5.0.0",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.18 || >=20"
+ },
+ "peerDependencies": {
+ "eslint": ">=9"
+ }
+ },
+ "node_modules/eslint-plugin-ava/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-ava/node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc": {
+ "version": "52.0.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-52.0.4.tgz",
+ "integrity": "sha512-be5OzGlLExvcK13Il3noU7/v7WmAQGenTmCaBKf1pwVtPOb6X+PGFVnJad0QhMj4KKf45XjE4hbsBxv25q1fTg==",
+ "dev": true,
+ "dependencies": {
+ "@es-joy/jsdoccomment": "~0.52.0",
+ "are-docs-informative": "^0.0.2",
+ "comment-parser": "1.4.1",
+ "debug": "^4.4.1",
+ "escape-string-regexp": "^4.0.0",
+ "espree": "^10.4.0",
+ "esquery": "^1.6.0",
+ "parse-imports-exports": "^0.2.4",
+ "semver": "^7.7.2",
+ "spdx-expression-parse": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.11.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-scope/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=5"
+ }
+ },
+ "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/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,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/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
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/eslint/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/esmock": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esmock/-/esmock-2.7.3.tgz",
+ "integrity": "sha512-/M/YZOjgyLaVoY6K83pwCsGE1AJQnj4S4GyXLYgi/Y79KL8EeW6WU7Rmjc89UO7jv6ec8+j34rKeWOfiLeEu0A==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16.0"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/espurify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/espurify/-/espurify-2.1.1.tgz",
+ "integrity": "sha512-zttWvnkhcDyGOhSH4vO2qCBILpdCMv/MX8lp4cqgRkQoDRGK2oZxi2GfWhlP2dIXmk7BaKeOTuzbHhyC68o8XQ==",
+ "dev": true
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/events-to-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
+ "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==",
+ "dev": true
+ },
+ "node_modules/execa": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz",
+ "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "figures": "^6.1.0",
+ "get-stream": "^9.0.0",
+ "human-signals": "^8.0.1",
+ "is-plain-obj": "^4.1.0",
+ "is-stream": "^4.0.1",
+ "npm-run-path": "^6.0.0",
+ "pretty-ms": "^9.2.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^4.0.0",
+ "yoctocolors": "^2.1.1"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "dev": true,
+ "dependencies": {
+ "homedir-polyfill": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/exponential-backoff": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz",
+ "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA=="
+ },
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/fast-deep-equal": {
+ "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=="
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "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=="
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/figures": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
+ "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
+ "dependencies": {
+ "is-unicode-supported": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/file-type": {
+ "version": "18.7.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.7.0.tgz",
+ "integrity": "sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw==",
+ "dev": true,
+ "dependencies": {
+ "readable-web-to-node-stream": "^3.0.2",
+ "strtok3": "^7.0.0",
+ "token-types": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/file-type?sponsor=1"
+ }
+ },
+ "node_modules/file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "dev": true
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up-simple": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
+ "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/findup-sync": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
+ "dev": true,
+ "dependencies": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
+ "resolve-dir": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fromentries": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
+ "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
+ "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/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==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
+ "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-port": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/get-port/-/get-port-6.1.2.tgz",
+ "integrity": "sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
+ "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
+ "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
+ "dev": true,
+ "dependencies": {
+ "@sec-ant/readable-stream": "^0.4.1",
+ "is-stream": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/global-directory/node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "dependencies": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "dev": true,
+ "dependencies": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/global-prefix/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/global-prefix/node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/global-prefix/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
+ "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz",
+ "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^2.1.0",
+ "fast-glob": "^3.3.3",
+ "ignore": "^7.0.3",
+ "path-type": "^6.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/@sindresorhus/merge-streams": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
+ "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/globby/node_modules/path-type": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz",
+ "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+ },
+ "node_modules/handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg=="
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasha": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
+ "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
+ "dev": true,
+ "dependencies": {
+ "is-stream": "^2.0.0",
+ "type-fest": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/hasha/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "dependencies": {
+ "parse-passwd": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz",
+ "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==",
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/hosted-git-info/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "node_modules/hpack.js/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/hpack.js/node_modules/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=="
+ },
+ "node_modules/hpack.js/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/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
+ },
+ "node_modules/htmlparser2": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+ "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "entities": "^4.5.0"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
+ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="
+ },
+ "node_modules/http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw=="
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz",
+ "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/ignore-by-default": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz",
+ "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10 <11 || >=12 <13 || >=14"
+ }
+ },
+ "node_modules/ignore-walk": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz",
+ "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==",
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/ignore-walk/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/ignore-walk/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-fresh/node_modules/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==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-local/node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/import-modules": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz",
+ "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/index-to-position": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz",
+ "integrity": "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ini": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz",
+ "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
+ "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/irregular-plurals": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz",
+ "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-in-ci": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-1.0.0.tgz",
+ "integrity": "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==",
+ "bin": {
+ "is-in-ci": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz",
+ "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==",
+ "dependencies": {
+ "global-directory": "^4.0.1",
+ "is-path-inside": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-lambda": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+ "dev": true
+ },
+ "node_modules/is-npm": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz",
+ "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-like": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
+ "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
+ "dependencies": {
+ "lodash.isfinite": "^3.3.2"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
+ "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
+ },
+ "node_modules/is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
+ "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+ "dev": true
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+ "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ },
+ "node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-hook": {
+ "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,
+ "dependencies": {
+ "append-transform": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz",
+ "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==",
+ "dev": true,
+ "dependencies": {
+ "archy": "^1.0.0",
+ "cross-spawn": "^7.0.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "p-map": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "uuid": "^8.3.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo/node_modules/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,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/js-string-escape": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
+ "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/js2xmlparser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
+ "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
+ "dependencies": {
+ "xmlcreate": "^2.0.4"
+ }
+ },
+ "node_modules/jsdoc": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz",
+ "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==",
+ "dependencies": {
+ "@babel/parser": "^7.20.15",
+ "@jsdoc/salty": "^0.2.1",
+ "@types/markdown-it": "^14.1.1",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.9.0",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.2",
+ "klaw": "^3.0.0",
+ "markdown-it": "^14.1.0",
+ "markdown-it-anchor": "^8.6.7",
+ "marked": "^4.0.10",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "underscore": "~1.13.2"
+ },
+ "bin": {
+ "jsdoc": "jsdoc.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
+ "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsdoc/node_modules/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==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz",
+ "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/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=="
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/json-stringify-nice": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz",
+ "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "engines": [
+ "node >= 0.2.0"
+ ]
+ },
+ "node_modules/just-diff": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz",
+ "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==",
+ "dev": true
+ },
+ "node_modules/just-diff-apply": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz",
+ "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==",
+ "dev": true
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dependencies": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "node_modules/ky": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/ky/-/ky-1.10.0.tgz",
+ "integrity": "sha512-YRPCzHEWZffbfvmRrfwa+5nwBHwZuYiTrfDX0wuhGBPV0pA/zCqcOq93MDssON/baIkpYbvehIX5aLpMxrRhaA==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/ky?sponsor=1"
+ }
+ },
+ "node_modules/latest-version": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-9.0.0.tgz",
+ "integrity": "sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==",
+ "dependencies": {
+ "package-json": "^10.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/less-openui5": {
+ "version": "0.11.6",
+ "resolved": "https://registry.npmjs.org/less-openui5/-/less-openui5-0.11.6.tgz",
+ "integrity": "sha512-sQmU+G2pJjFfzRI+XtXkk+T9G0s6UmWWUfOW0utPR46C9lfhNr4DH1lNJuImj64reXYi+vOwyNxPRkj0F3mofA==",
+ "dependencies": {
+ "@adobe/css-tools": "^4.0.2",
+ "clone": "^2.1.2",
+ "mime": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 10",
+ "npm": ">= 5"
+ }
+ },
+ "node_modules/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,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/licensee": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/licensee/-/licensee-11.1.1.tgz",
+ "integrity": "sha512-FpgdKKjvJULlBqYiKtrK7J4Oo7sQO1lHQTUOcxxE4IPQccx6c0tJWMgwVdG46+rPnLPSV7EWD6eWUtAjGO52Lg==",
+ "dev": true,
+ "dependencies": {
+ "@blueoak/list": "^15.0.0",
+ "@npmcli/arborist": "^7.2.1",
+ "correct-license-metadata": "^1.4.0",
+ "docopt": "^0.6.2",
+ "hasown": "^2.0.0",
+ "npm-license-corrections": "^1.6.2",
+ "semver": "^7.6.0",
+ "spdx-expression-parse": "^4.0.0",
+ "spdx-expression-validate": "^2.0.0",
+ "spdx-osi": "^3.0.0",
+ "spdx-whitelisted": "^1.0.0"
+ },
+ "bin": {
+ "licensee": "licensee"
+ },
+ "engines": {
+ "node": "^18.12 || ^20.9 || >= 22.7"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "node_modules/load-json-file": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz",
+ "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lockfile": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz",
+ "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==",
+ "dependencies": {
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "node_modules/lockfile/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "dev": true
+ },
+ "node_modules/lodash.flattendeep": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+ "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
+ "dev": true
+ },
+ "node_modules/lodash.isfinite": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
+ "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA=="
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.19",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
+ "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/make-dir": {
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/make-fetch-happen": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz",
+ "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==",
+ "dependencies": {
+ "@npmcli/agent": "^3.0.0",
+ "cacache": "^19.0.1",
+ "http-cache-semantics": "^4.1.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^4.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^1.0.0",
+ "proc-log": "^5.0.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^12.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/@npmcli/fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz",
+ "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/cacache": {
+ "version": "19.0.1",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz",
+ "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==",
+ "dependencies": {
+ "@npmcli/fs": "^4.0.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^7.0.2",
+ "ssri": "^12.0.0",
+ "tar": "^7.4.3",
+ "unique-filename": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/make-fetch-happen/node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/ssri": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz",
+ "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/unique-filename": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz",
+ "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==",
+ "dependencies": {
+ "unique-slug": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/unique-slug": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz",
+ "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it-anchor": {
+ "version": "8.6.7",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz",
+ "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==",
+ "peerDependencies": {
+ "@types/markdown-it": "*",
+ "markdown-it": "*"
+ }
+ },
+ "node_modules/marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/matcher": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz",
+ "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^5.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/md5-hex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz",
+ "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==",
+ "dev": true,
+ "dependencies": {
+ "blueimp-md5": "^2.10.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memoize": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/memoize/-/memoize-10.1.0.tgz",
+ "integrity": "sha512-MMbFhJzh4Jlg/poq1si90XRlTZRDHVqdlz2mPyGJ6kqMpyHUyVpDd5gpFAvVehW64+RA1eKE9Yt8aSLY7w2Kgg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-function": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/memoize?sponsor=1"
+ }
+ },
+ "node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micro-spelling-correcter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/micro-spelling-correcter/-/micro-spelling-correcter-1.1.1.tgz",
+ "integrity": "sha512-lkJ3Rj/mtjlRcHk6YyCbvZhyWTOzdBvTHsxMmZSk5jxN1YyVSQ+JETAom55mdzfcyDrY/49Z7UCW760BK30crg==",
+ "dev": true
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ },
+ "node_modules/minimatch": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
+ "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
+ "dependencies": {
+ "@isaacs/brace-expansion": "^5.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz",
+ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-fetch": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz",
+ "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==",
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^3.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-flush/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-flush/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/minizlib": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
+ "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/multimatch": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
+ "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
+ "dev": true,
+ "dependencies": {
+ "@types/minimatch": "^3.0.3",
+ "array-differ": "^3.0.0",
+ "array-union": "^2.1.0",
+ "arrify": "^2.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/multimatch/node_modules/arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/multimatch/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-gyp": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz",
+ "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==",
+ "dev": true,
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^13.0.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^4.1.0",
+ "semver": "^7.3.5",
+ "tar": "^6.2.1",
+ "which": "^4.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+ "dev": true,
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/node-gyp/node_modules/@npmcli/agent": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
+ "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/abbrev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-gyp/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/node-gyp/node_modules/make-fetch-happen": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
+ "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/minipass-fetch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
+ "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/node-gyp/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/nopt": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-gyp/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/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,
+ "dependencies": {
+ "process-on-spawn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.21",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz",
+ "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==",
+ "dev": true
+ },
+ "node_modules/node-stream-zip": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz",
+ "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==",
+ "engines": {
+ "node": ">=0.12.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/antelle"
+ }
+ },
+ "node_modules/nofilter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz",
+ "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.19"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz",
+ "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==",
+ "dependencies": {
+ "abbrev": "^3.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz",
+ "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-bundled": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz",
+ "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==",
+ "dev": true,
+ "dependencies": {
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-install-checks": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz",
+ "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-license-corrections": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/npm-license-corrections/-/npm-license-corrections-1.9.0.tgz",
+ "integrity": "sha512-9Tq6y6zop5lsZy6dInbgrCLnqtuN+3jBc9NCusKjbeQL4LRudDkvmCYyInsDOaKN7GIVbBSvDto5MnEqYXVhxQ==",
+ "dev": true
+ },
+ "node_modules/npm-normalize-package-bin": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
+ "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-package-arg": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz",
+ "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-package-arg/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-package-arg/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/npm-package-arg/node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-packlist": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz",
+ "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==",
+ "dependencies": {
+ "ignore-walk": "^7.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-pick-manifest": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz",
+ "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==",
+ "dependencies": {
+ "npm-install-checks": "^7.1.0",
+ "npm-normalize-package-bin": "^4.0.0",
+ "npm-package-arg": "^12.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-pick-manifest/node_modules/npm-install-checks": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.2.tgz",
+ "integrity": "sha512-z9HJBCYw9Zr8BqXcllKIs5nI+QggAImbBdHphOzVYrz2CB4iQ6FzWyKmlqDZua+51nAu7FcemlbTc9VgQN5XDQ==",
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz",
+ "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-pick-manifest/node_modules/npm-package-arg": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz",
+ "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==",
+ "dependencies": {
+ "hosted-git-info": "^8.0.0",
+ "proc-log": "^5.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^6.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-pick-manifest/node_modules/validate-npm-package-name": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz",
+ "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-registry-fetch": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz",
+ "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/redact": "^2.0.0",
+ "jsonparse": "^1.3.1",
+ "make-fetch-happen": "^13.0.0",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minizlib": "^2.1.2",
+ "npm-package-arg": "^11.0.0",
+ "proc-log": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/@npmcli/agent": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
+ "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
+ "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/minipass-fetch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
+ "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-registry-fetch/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/npm-run-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
+ "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^4.0.0",
+ "unicorn-magic": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/nyc": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz",
+ "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==",
+ "dev": true,
+ "dependencies": {
+ "@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": "^3.3.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": "^6.0.2",
+ "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": "^2.0.0",
+ "test-exclude": "^6.0.0",
+ "yargs": "^15.0.2"
+ },
+ "bin": {
+ "nyc": "bin/nyc.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/nyc/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/nyc/node_modules/cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "node_modules/nyc/node_modules/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,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/nyc/node_modules/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
+ },
+ "node_modules/nyc/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
+ "node_modules/nyc/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/nyc/node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/nyc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/nyc/node_modules/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,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/nyc/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/nyc/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/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,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
+ "node_modules/nyc/node_modules/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,
+ "dependencies": {
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/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,
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
+ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open-cli": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/open-cli/-/open-cli-8.0.0.tgz",
+ "integrity": "sha512-3muD3BbfLyzl+aMVSEfn2FfOqGdPYR0O4KNnxXsLEPE2q9OSjBfJAaB6XKbrUzLgymoSMejvb5jpXJfru/Ko2A==",
+ "dev": true,
+ "dependencies": {
+ "file-type": "^18.7.0",
+ "get-stdin": "^9.0.0",
+ "meow": "^12.1.1",
+ "open": "^10.0.0",
+ "tempy": "^3.1.0"
+ },
+ "bin": {
+ "open-cli": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "dependencies": {
+ "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.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz",
+ "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-config": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/package-config/-/package-config-5.0.0.tgz",
+ "integrity": "sha512-GYTTew2slBcYdvRHqjhwaaydVMvn/qrGC323+nKclYioNSLTDUM/lGgtGTgyHVtYcozb+XkE8CNhwcraOmZ9Mg==",
+ "dev": true,
+ "dependencies": {
+ "find-up-simple": "^1.0.0",
+ "load-json-file": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-hash": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
+ "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.15",
+ "hasha": "^5.0.0",
+ "lodash.flattendeep": "^4.4.0",
+ "release-zalgo": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/package-json": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz",
+ "integrity": "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==",
+ "dependencies": {
+ "ky": "^1.2.0",
+ "registry-auth-token": "^5.0.2",
+ "registry-url": "^6.0.1",
+ "semver": "^7.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
+ },
+ "node_modules/pacote": {
+ "version": "19.0.1",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-19.0.1.tgz",
+ "integrity": "sha512-zIpxWAsr/BvhrkSruspG8aqCQUUrWtpwx0GjiRZQhEM/pZXrigA32ElN3vTcCPUDOFmHr6SFxwYrvVUs5NTEUg==",
+ "dependencies": {
+ "@npmcli/git": "^6.0.0",
+ "@npmcli/installed-package-contents": "^3.0.0",
+ "@npmcli/package-json": "^6.0.0",
+ "@npmcli/promise-spawn": "^8.0.0",
+ "@npmcli/run-script": "^9.0.0",
+ "cacache": "^19.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^12.0.0",
+ "npm-packlist": "^9.0.0",
+ "npm-pick-manifest": "^10.0.0",
+ "npm-registry-fetch": "^18.0.0",
+ "proc-log": "^5.0.0",
+ "promise-retry": "^2.0.1",
+ "sigstore": "^3.0.0",
+ "ssri": "^12.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "bin/index.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/@npmcli/fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz",
+ "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/@npmcli/installed-package-contents": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz",
+ "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==",
+ "dependencies": {
+ "npm-bundled": "^4.0.0",
+ "npm-normalize-package-bin": "^4.0.0"
+ },
+ "bin": {
+ "installed-package-contents": "bin/index.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/@npmcli/node-gyp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz",
+ "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/@npmcli/redact": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz",
+ "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/@npmcli/run-script": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz",
+ "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==",
+ "dependencies": {
+ "@npmcli/node-gyp": "^4.0.0",
+ "@npmcli/package-json": "^6.0.0",
+ "@npmcli/promise-spawn": "^8.0.0",
+ "node-gyp": "^11.0.0",
+ "proc-log": "^5.0.0",
+ "which": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/cacache": {
+ "version": "19.0.1",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz",
+ "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==",
+ "dependencies": {
+ "@npmcli/fs": "^4.0.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^7.0.2",
+ "ssri": "^12.0.0",
+ "tar": "^7.4.3",
+ "unique-filename": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/cacache/node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/pacote/node_modules/cacache/node_modules/tar": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.0.1",
+ "mkdirp": "^3.0.1",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/pacote/node_modules/cacache/node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/pacote/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/pacote/node_modules/node-gyp": {
+ "version": "11.4.2",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.4.2.tgz",
+ "integrity": "sha512-3gD+6zsrLQH7DyYOUIutaauuXrcyxeTPyQuZQCQoNPZMHMMS5m4y0xclNpvYzoK3VNzuyxT6eF4mkIL4WSZ1eQ==",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^14.0.3",
+ "nopt": "^8.0.0",
+ "proc-log": "^5.0.0",
+ "semver": "^7.3.5",
+ "tar": "^7.4.3",
+ "tinyglobby": "^0.2.12",
+ "which": "^5.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/node-gyp/node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/pacote/node_modules/node-gyp/node_modules/tar": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.0.1",
+ "mkdirp": "^3.0.1",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/pacote/node_modules/node-gyp/node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/pacote/node_modules/npm-bundled": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz",
+ "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==",
+ "dependencies": {
+ "npm-normalize-package-bin": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/npm-normalize-package-bin": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz",
+ "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/npm-package-arg": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz",
+ "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==",
+ "dependencies": {
+ "hosted-git-info": "^8.0.0",
+ "proc-log": "^5.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^6.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/npm-registry-fetch": {
+ "version": "18.0.2",
+ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz",
+ "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==",
+ "dependencies": {
+ "@npmcli/redact": "^3.0.0",
+ "jsonparse": "^1.3.1",
+ "make-fetch-happen": "^14.0.0",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^4.0.0",
+ "minizlib": "^3.0.1",
+ "npm-package-arg": "^12.0.0",
+ "proc-log": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/ssri": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz",
+ "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/pacote/node_modules/tar/node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/pacote/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/pacote/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pacote/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pacote/node_modules/tar/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/pacote/node_modules/tar/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pacote/node_modules/unique-filename": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz",
+ "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==",
+ "dependencies": {
+ "unique-slug": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/unique-slug": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz",
+ "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/validate-npm-package-name": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz",
+ "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/pacote/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parent-module/node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-conflict-json": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-3.0.1.tgz",
+ "integrity": "sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==",
+ "dev": true,
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "just-diff": "^6.0.0",
+ "just-diff-apply": "^5.2.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/parse-conflict-json/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/parse-imports-exports": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz",
+ "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==",
+ "dev": true,
+ "dependencies": {
+ "parse-statements": "1.0.11"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@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"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse-json/node_modules/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
+ },
+ "node_modules/parse-ms": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse-statements": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz",
+ "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==",
+ "dev": true
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "dependencies": {
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/peek-readable": {
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.4.2.tgz",
+ "integrity": "sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz",
+ "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/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,
+ "dependencies": {
+ "semver-compare": "^1.0.0"
+ }
+ },
+ "node_modules/plur": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz",
+ "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==",
+ "dev": true,
+ "dependencies": {
+ "irregular-plurals": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/portscanner": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz",
+ "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==",
+ "dependencies": {
+ "async": "^2.6.0",
+ "is-number-like": "^1.0.3"
+ },
+ "engines": {
+ "node": ">=0.4",
+ "npm": ">=1.0.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/pretty-data": {
+ "version": "0.40.0",
+ "resolved": "https://registry.npmjs.org/pretty-data/-/pretty-data-0.40.0.tgz",
+ "integrity": "sha512-YFLnEdDEDnkt/GEhet5CYZHCvALw6+Elyb/tp8kQG03ZSIuzeaDWpZYndCXwgqu4NAjh1PI534dhDS1mHarRnQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/pretty-ms": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
+ "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==",
+ "dev": true,
+ "dependencies": {
+ "parse-ms": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/proc-log": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz",
+ "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "node_modules/process-on-spawn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz",
+ "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==",
+ "dev": true,
+ "dependencies": {
+ "fromentries": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/proggy": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/proggy/-/proggy-2.0.0.tgz",
+ "integrity": "sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/promise-all-reject-late": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz",
+ "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/promise-call-limit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz",
+ "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+ "dev": true
+ },
+ "node_modules/promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pupa": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz",
+ "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==",
+ "dependencies": {
+ "escape-goat": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/quibble": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/quibble/-/quibble-0.9.2.tgz",
+ "integrity": "sha512-BrL7hrZcbyyt5ZDfePkGFDc3m82uUtxCPOnpRUrkOdtBnmV9ldQKxXORkKL8eIzToRNaCpIPyKyfdfq/tBlFAA==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.21",
+ "resolve": "^1.22.8"
+ },
+ "engines": {
+ "node": ">= 0.14.0"
+ }
+ },
+ "node_modules/random-int": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/random-int/-/random-int-3.1.0.tgz",
+ "integrity": "sha512-h8CRz8cpvzj0hC/iH/1Gapgcl2TQ6xtnCpyOI5WvWfXf/yrDx2DOU+tD9rX23j36IF11xg1KqB9W11Z18JPMdw==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read-cmd-shim": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz",
+ "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-json-fast": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
+ "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==",
+ "dev": true,
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-up": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
+ "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==",
+ "dependencies": {
+ "find-up-simple": "^1.0.0",
+ "read-pkg": "^9.0.0",
+ "type-fest": "^4.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-package-up/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
+ "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
+ "dependencies": {
+ "@types/normalize-package-data": "^2.4.3",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^8.0.0",
+ "type-fest": "^4.6.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg/node_modules/parse-json": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz",
+ "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "index-to-position": "^1.1.0",
+ "type-fest": "^4.39.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg/node_modules/unicorn-magic": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+ "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+ "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+ "dev": true,
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "process": "^0.11.10",
+ "string_decoder": "^1.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/readable-web-to-node-stream": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz",
+ "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==",
+ "dev": true,
+ "dependencies": {
+ "readable-stream": "^4.7.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/registry-auth-token": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz",
+ "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==",
+ "dependencies": {
+ "@pnpm/npm-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/registry-url": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz",
+ "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==",
+ "dependencies": {
+ "rc": "1.2.8"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/release-zalgo": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
+ "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==",
+ "dev": true,
+ "dependencies": {
+ "es6-error": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/replacestream": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz",
+ "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.3",
+ "object-assign": "^4.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/replacestream/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/replacestream/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/replacestream/node_modules/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=="
+ },
+ "node_modules/replacestream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "node_modules/require-package-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
+ "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==",
+ "dev": true
+ },
+ "node_modules/requizzle": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz",
+ "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==",
+ "dependencies": {
+ "lodash": "^4.17.21"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "dev": true,
+ "dependencies": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
+ "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^11.0.0",
+ "package-json-from-dist": "^1.0.0"
+ },
+ "bin": {
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
+ "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^3.3.1",
+ "jackspeak": "^4.1.1",
+ "minimatch": "^10.0.3",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/jackspeak": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
+ "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
+ "dev": true,
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/lru-cache": {
+ "version": "11.2.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz",
+ "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==",
+ "dev": true,
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/rimraf/node_modules/path-scurry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
+ "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/router/node_modules/path-to-regexp": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/sax": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
+ "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+ },
+ "node_modules/select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg=="
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+ "dev": true
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/serialize-error/node_modules/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,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "dev": true
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "node_modules/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==",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sigstore": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz",
+ "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==",
+ "dependencies": {
+ "@sigstore/bundle": "^3.1.0",
+ "@sigstore/core": "^2.0.0",
+ "@sigstore/protobuf-specs": "^0.4.0",
+ "@sigstore/sign": "^3.1.0",
+ "@sigstore/tuf": "^3.1.0",
+ "@sigstore/verify": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/sinon": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.0.tgz",
+ "integrity": "sha512-TOgRcwFPbfGtpqvZw+hyqJDvqfapr1qUlOizROIk4bBLjlsjlB00Pg6wMFXNtJRpu+eCZuVOaLatG7M8105kAw==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "@sinonjs/fake-timers": "^13.0.5",
+ "@sinonjs/samsam": "^8.0.1",
+ "diff": "^7.0.0",
+ "supports-color": "^7.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/slash": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.7",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz",
+ "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
+ "dependencies": {
+ "ip-address": "^10.0.1",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/spawn-wrap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
+ "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
+ "dev": true,
+ "dependencies": {
+ "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": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/foreground-child": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/spawn-wrap/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/spawn-wrap/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/spdx-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz",
+ "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==",
+ "dev": true,
+ "dependencies": {
+ "array-find-index": "^1.0.2",
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-ranges": "^2.0.0"
+ }
+ },
+ "node_modules/spdx-compare/node_modules/spdx-expression-parse": {
+ "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,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+ "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-expression-validate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz",
+ "integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-expression-validate/node_modules/spdx-expression-parse": {
+ "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,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.22",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz",
+ "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ=="
+ },
+ "node_modules/spdx-osi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-osi/-/spdx-osi-3.0.0.tgz",
+ "integrity": "sha512-7DZMaD/rNHWGf82qWOazBsLXQsaLsoJb9RRjhEUQr5o86kw3A1ErGzSdvaXl+KalZyKkkU5T2a5NjCCutAKQSw==",
+ "dev": true
+ },
+ "node_modules/spdx-ranges": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz",
+ "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==",
+ "dev": true
+ },
+ "node_modules/spdx-whitelisted": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-whitelisted/-/spdx-whitelisted-1.0.0.tgz",
+ "integrity": "sha512-X4FOpUCvZuo42MdB1zAZ/wdX4N0lLcWDozf2KYFVDgtLv8Lx+f31LOYLP2/FcwTzsPi64bS/VwKqklI4RBletg==",
+ "dev": true,
+ "dependencies": {
+ "spdx-compare": "^1.0.0",
+ "spdx-ranges": "^2.0.0"
+ }
+ },
+ "node_modules/spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "detect-node": "^2.0.4",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.2",
+ "readable-stream": "^3.0.6",
+ "wbuf": "^1.7.3"
+ }
+ },
+ "node_modules/spdy-transport/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "node_modules/ssri": {
+ "version": "10.0.6",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz",
+ "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/stack-utils/node_modules/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==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+ "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==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/is-fullwidth-code-point": {
+ "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==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/stringify-object-es5": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/stringify-object-es5/-/stringify-object-es5-2.5.0.tgz",
+ "integrity": "sha512-vE7Xdx9ylG4JI16zy7/ObKUB+MtxuMcWlj/WHHr3+yAlQoN6sst2stU9E+2Qs3OrlJw/Pf3loWxL1GauEHf6MA==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-obj": "^1.0.0",
+ "is-regexp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stringify-object-es5/node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
+ "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "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==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strtok3": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.1.1.tgz",
+ "integrity": "sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==",
+ "dev": true,
+ "dependencies": {
+ "@tokenizer/token": "^0.3.0",
+ "peek-readable": "^5.1.3"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/stubborn-fs": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-1.2.5.tgz",
+ "integrity": "sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g=="
+ },
+ "node_modules/supertap": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz",
+ "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==",
+ "dev": true,
+ "dependencies": {
+ "indent-string": "^5.0.0",
+ "js-yaml": "^3.14.1",
+ "serialize-error": "^7.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/supertap/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/supertap/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/supports-color": {
+ "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,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tap-parser": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.2.2.tgz",
+ "integrity": "sha512-uXKcosa0qoSjeh73dhmX+OpJvpigDxUciOhBcbGUKtmwzEFJjUT1Ql5dpg4M9I1UjXT9b+6n1W05FB8QmKossA==",
+ "dev": true,
+ "dependencies": {
+ "events-to-array": "^1.0.1",
+ "inherits": "~2.0.1",
+ "js-yaml": "^3.2.7"
+ },
+ "bin": {
+ "tap-parser": "bin/cmd.js"
+ },
+ "optionalDependencies": {
+ "readable-stream": "^2"
+ }
+ },
+ "node_modules/tap-parser/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/tap-parser/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/tap-parser/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/tap-parser/node_modules/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==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/tap-parser/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/tap-xunit": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tap-xunit/-/tap-xunit-2.4.1.tgz",
+ "integrity": "sha512-qcZStDtjjYjMKAo7QNiCtOW256g3tuSyCSe5kNJniG1Q2oeOExJq4vm8CwboHZURpkXAHvtqMl4TVL7mcbMVVA==",
+ "dev": true,
+ "dependencies": {
+ "duplexer": "~0.1.1",
+ "minimist": "~1.2.0",
+ "tap-parser": "~1.2.2",
+ "through2": "~2.0.0",
+ "xmlbuilder": "~4.2.0",
+ "xtend": "~4.0.0"
+ },
+ "bin": {
+ "tap-xunit": "bin/tap-xunit",
+ "txunit": "bin/tap-xunit"
+ }
+ },
+ "node_modules/tar": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.0.1",
+ "mkdirp": "^3.0.1",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tar/node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/tar/node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/temp-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz",
+ "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/tempy": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz",
+ "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==",
+ "dev": true,
+ "dependencies": {
+ "is-stream": "^3.0.0",
+ "temp-dir": "^3.0.0",
+ "type-fest": "^2.12.2",
+ "unique-string": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.44.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz",
+ "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/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,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/testdouble": {
+ "version": "3.20.2",
+ "resolved": "https://registry.npmjs.org/testdouble/-/testdouble-3.20.2.tgz",
+ "integrity": "sha512-790e9vJKdfddWNOaxW1/V9FcMk48cPEl3eJSj2i8Hh1fX89qArEJ6cp3DBnaECpGXc3xKJVWbc1jeNlWYWgiMg==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.21",
+ "quibble": "^0.9.2",
+ "stringify-object-es5": "^2.5.0",
+ "theredoc": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/theredoc": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/theredoc/-/theredoc-1.0.0.tgz",
+ "integrity": "sha512-KU3SA3TjRRM932jpNfD3u4Ec3bSvedyo5ITPI7zgWYnKep7BwQQaxlhI9qbO+lKJoRnoAbEVfMcAHRuKVYikDA==",
+ "dev": true
+ },
+ "node_modules/through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/through2/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/through2/node_modules/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==",
+ "dev": true
+ },
+ "node_modules/through2/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/time-zone": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz",
+ "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/token-types": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz",
+ "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==",
+ "dev": true,
+ "dependencies": {
+ "@tokenizer/token": "^0.3.0",
+ "ieee754": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true
+ },
+ "node_modules/treeverse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz",
+ "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/tuf-js": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.1.0.tgz",
+ "integrity": "sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==",
+ "dependencies": {
+ "@tufjs/models": "3.0.1",
+ "debug": "^4.4.1",
+ "make-fetch-happen": "^14.0.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/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,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
+ },
+ "node_modules/underscore": {
+ "version": "1.13.7",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz",
+ "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g=="
+ },
+ "node_modules/undici": {
+ "version": "6.21.3",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
+ "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unique-filename": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
+ "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==",
+ "dev": true,
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/unique-slug": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz",
+ "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
+ "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==",
+ "dev": true,
+ "dependencies": {
+ "crypto-random-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/update-notifier": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-7.3.1.tgz",
+ "integrity": "sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==",
+ "dependencies": {
+ "boxen": "^8.0.1",
+ "chalk": "^5.3.0",
+ "configstore": "^7.0.0",
+ "is-in-ci": "^1.0.0",
+ "is-installed-globally": "^1.0.0",
+ "is-npm": "^6.0.0",
+ "latest-version": "^9.0.0",
+ "pupa": "^3.1.0",
+ "semver": "^7.6.3",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/update-notifier?sponsor=1"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/validate-npm-package-name": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz",
+ "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/walk-up-path": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz",
+ "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA=="
+ },
+ "node_modules/wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dependencies": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true
+ },
+ "node_modules/well-known-symbols": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz",
+ "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/when-exit": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.4.tgz",
+ "integrity": "sha512-4rnvd3A1t16PWzrBUcSDZqcAmsUIy4minDXT/CZ8F2mVDgd65i4Aalimgz1aQkRGU0iH5eT5+6Rx2TK8o443Pg=="
+ },
+ "node_modules/which": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz",
+ "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/which-module": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
+ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
+ "dev": true
+ },
+ "node_modules/widest-line": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz",
+ "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==",
+ "dependencies": {
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/widest-line/node_modules/emoji-regex": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz",
+ "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg=="
+ },
+ "node_modules/widest-line/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "9.3.4",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz",
+ "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg=="
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/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==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/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=="
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/write-file-atomic": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz",
+ "integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xdg-basedir": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
+ "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
+ "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xml2js/node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
+ "integrity": "sha512-oEePiEefhQhAeUnwRnIBLBWmk/fsWWbQ53EEWsRuzECbQ3m5o/Esmq6H47CYYwSLW+Ynt0rS9hd0pd2ogMAWjg==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/xmlcreate": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
+ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg=="
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/yaml-ast-parser": {
+ "version": "0.0.43",
+ "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz",
+ "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A=="
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yesno": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/yesno/-/yesno-0.4.0.tgz",
+ "integrity": "sha512-tdBxmHvbXPBKYIg81bMCB7bVeDmHkRzk5rVJyYYXurwKkHq/MCd8rz4HSJUP7hW0H2NlXiq8IFiWvYKEHhlotA=="
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yoctocolors": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz",
+ "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/packages/cli/package.json b/packages/cli/package.json
new file mode 100644
index 00000000000..4a8a12ea44f
--- /dev/null
+++ b/packages/cli/package.json
@@ -0,0 +1,159 @@
+{
+ "name": "@ui5/cli",
+ "version": "4.0.26",
+ "description": "UI5 CLI - CLI",
+ "author": {
+ "name": "SAP SE",
+ "email": "openui5@sap.com",
+ "url": "https://www.sap.com"
+ },
+ "license": "Apache-2.0",
+ "keywords": [
+ "openui5",
+ "sapui5",
+ "ui5",
+ "build",
+ "development",
+ "tool"
+ ],
+ "bin": {
+ "ui5": "./bin/ui5.cjs"
+ },
+ "type": "module",
+ "exports": {
+ "./bin/ui5.js": "./bin/ui5.cjs",
+ "./bin/ui5.cjs": "./bin/ui5.cjs",
+ "./package.json": "./package.json"
+ },
+ "engines": {
+ "node": "^20.11.0 || >=22.0.0",
+ "npm": ">= 8"
+ },
+ "scripts": {
+ "test": "npm run lint && npm run jsdoc-generate && npm run coverage && npm run depcheck && npm run check-licenses",
+ "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": "npm run unit -- --watch",
+ "unit-xunit": "rimraf test/tmp && ava --node-arguments=\"--experimental-loader=@istanbuljs/esm-loader-hook\" --tap | tap-xunit --dontUseCommentsAsTestNames=true > test-results.xml",
+ "unit-inspect": "cross-env UI5_LOG_LVL=verbose ava debug --break",
+ "coverage": "rimraf test/tmp && nyc ava --node-arguments=\"--experimental-loader=@istanbuljs/esm-loader-hook\"",
+ "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": "jsdoc -c ./jsdoc.json -t $(node -p 'path.dirname(require.resolve(\"docdash\"))') ./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 --sort semver --next-tag v$npm_package_version -o CHANGELOG.md v4.0.0.. && git add CHANGELOG.md",
+ "prepublishOnly": "git push --follow-tags",
+ "release-note": "git-chglog --sort semver -c .chglog/release-config.yml v$npm_package_version | node .chglog/consolidate-changelogs.js",
+ "depcheck": "depcheck --ignores @ui5/cli,rimraf,docdash,@istanbuljs/esm-loader-hook,@ui5/fs,@ui5/builder",
+ "check-licenses": "licensee --errors-only"
+ },
+ "files": [
+ "CHANGELOG.md",
+ "CONTRIBUTING.md",
+ "jsdoc.json",
+ "npm-shrinkwrap.json",
+ "bin/**",
+ "lib/**",
+ "LICENSES/**",
+ ".reuse/**"
+ ],
+ "ava": {
+ "files": [
+ "test/bin/**/*.js",
+ "test/lib/**/*.js"
+ ],
+ "nodeArguments": [
+ "--loader=esmock",
+ "--no-warnings"
+ ],
+ "workerThreads": false
+ },
+ "nyc": {
+ "reporter": [
+ "lcov",
+ "text",
+ "text-summary"
+ ],
+ "exclude": [
+ ".chglog/**",
+ "docs/**",
+ "jsdocs/**",
+ "coverage/**",
+ "test/**",
+ "jsdoc-plugin.cjs"
+ ],
+ "check-coverage": true,
+ "statements": 80,
+ "branches": 75,
+ "functions": 75,
+ "lines": 80,
+ "watermarks": {
+ "statements": [
+ 70,
+ 90
+ ],
+ "branches": [
+ 70,
+ 90
+ ],
+ "functions": [
+ 70,
+ 90
+ ],
+ "lines": [
+ 70,
+ 90
+ ]
+ },
+ "cache": true,
+ "all": true
+ },
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:SAP/ui5-cli.git"
+ },
+ "dependencies": {
+ "@ui5/builder": "^4.0.11",
+ "@ui5/fs": "^4.0.2",
+ "@ui5/logger": "^4.0.2",
+ "@ui5/project": "^4.0.6",
+ "@ui5/server": "^4.0.7",
+ "chalk": "^5.6.2",
+ "data-with-position": "^0.5.0",
+ "import-local": "^3.2.0",
+ "js-yaml": "^4.1.0",
+ "open": "^10.2.0",
+ "pretty-hrtime": "^1.0.3",
+ "semver": "^7.7.2",
+ "update-notifier": "^7.3.1",
+ "yargs": "^17.7.2"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.8.0",
+ "@istanbuljs/esm-loader-hook": "^0.3.0",
+ "ava": "^6.4.1",
+ "chokidar-cli": "^3.0.0",
+ "cross-env": "^7.0.3",
+ "depcheck": "^1.4.7",
+ "docdash": "^2.0.2",
+ "eslint": "^9.36.0",
+ "eslint-config-google": "^0.14.0",
+ "eslint-plugin-ava": "^15.1.0",
+ "eslint-plugin-jsdoc": "^52.0.4",
+ "esmock": "^2.7.3",
+ "execa": "^9.6.0",
+ "globals": "^16.4.0",
+ "jsdoc": "^4.0.4",
+ "licensee": "^11.1.1",
+ "nyc": "^17.1.0",
+ "open-cli": "^8.0.0",
+ "rimraf": "^6.0.1",
+ "sinon": "^21.0.0",
+ "strip-ansi": "^7.1.2",
+ "tap-xunit": "^2.4.1",
+ "testdouble": "^3.20.2"
+ }
+}
diff --git a/packages/cli/test/bin/ui5.js b/packages/cli/test/bin/ui5.js
new file mode 100644
index 00000000000..110b9081ddf
--- /dev/null
+++ b/packages/cli/test/bin/ui5.js
@@ -0,0 +1,379 @@
+import test from "ava";
+import sinonGlobal from "sinon";
+import {fileURLToPath} from "node:url";
+import {createRequire, Module} from "node:module";
+import chalk from "chalk";
+import * as td from "testdouble";
+
+const require = createRequire(import.meta.url);
+
+// Node's module loading has changed since 20.6.xx. As 'esmock' is unable to properly
+// mock dynamic imports within CommonJS modules, we need to use another alternative for this test.
+// 'testdouble' seems to work pretty well for that case, but for NodeJS versions below 20.6.xx it needs
+// a `--loader` flag and we already use that for 'esmock'.
+// The solution would be to use the old mocking for older NodeJs versions and
+// 'testdouble' for the ones after 20.6.xx (no flag required here).
+const [nodeMajorVer, NodeMinorVer] = process.versions.node.split(".").map(Number);
+const useTestdoubleMock = nodeMajorVer > 20 || (nodeMajorVer === 20 && NodeMinorVer >= 6);
+
+const globalSinonSandbox = sinonGlobal.createSandbox();
+const importLocalStub = globalSinonSandbox.stub();
+
+test.before(() => {
+ if (useTestdoubleMock === false) { // Legacy (manual) mocking
+ // Mock dependencies
+ // NOTE: esmock is not able to properly mock dynamic imports within a CJS script.
+ // Also it seems that the stub is cached somewhere else, so beforeEach/afterEach
+ // can't be used to renew it. But #reset takes care of resetting the stub between tests
+
+ const importLocalModule = new Module("import-local");
+ importLocalModule.exports = importLocalStub;
+ require.cache[require.resolve("import-local")] = importLocalModule;
+ }
+});
+
+test.beforeEach(async (t) => {
+ const sinon = t.context.sinon = sinonGlobal.createSandbox();
+ t.context.processStdoutWriteStub = sinon.stub(process.stdout, "write");
+ t.context.processStderrWriteStub = sinon.stub(process.stderr, "write");
+ t.context.originalArgv = process.argv;
+ process.env.UI5_CLI_TEST_BIN_RUN_MAIN = "false"; // prevent automatic execution of main function
+
+ if (useTestdoubleMock === true) { // NodeJS versions 20.6 and above
+ await td.replaceEsm("import-local", {default: importLocalStub});
+ }
+});
+
+test.afterEach.always((t) => {
+ process.argv = t.context.originalArgv;
+ t.context.sinon.restore();
+ globalSinonSandbox.reset();
+ useTestdoubleMock && td.reset();
+
+ // Allow re-requiring the module
+ delete require.cache[require.resolve("../../bin/ui5.cjs")];
+
+ // Clear mocked modules
+ delete require.cache[require.resolve("../../package.json")];
+ delete require.cache[require.resolve("semver")];
+
+ delete process.env.UI5_CLI_NO_LOCAL;
+ delete process.env.UI5_CLI_TEST_BIN_RUN_MAIN;
+});
+
+test.serial("checkRequirements: Using supported Node.js version", (t) => {
+ const {processStderrWriteStub} = t.context;
+
+ const {checkRequirements} = require("../../bin/ui5.cjs");
+
+ const returnValue = checkRequirements({
+ pkg: {
+ name: "ui5-cli-engines-test",
+ engines: {
+ node: ">= 18"
+ }
+ },
+ nodeVersion: "v20.0.0"
+ });
+
+ t.true(returnValue);
+ t.is(processStderrWriteStub.callCount, 0, "stderr info should not be provided");
+});
+
+test.serial("checkRequirements: Using unsupported Node.js version", (t) => {
+ const {processStderrWriteStub} = t.context;
+
+ const {checkRequirements} = require("../../bin/ui5.cjs");
+
+ const returnValue = checkRequirements({
+ pkg: {
+ name: "ui5-cli-engines-test",
+ engines: {
+ node: "^999"
+ }
+ },
+ nodeVersion: "v10.0.0"
+ });
+
+ t.false(returnValue);
+ t.is(processStderrWriteStub.callCount, 10, "console.log should be called 6 times");
+
+ t.deepEqual(processStderrWriteStub.getCall(0).args,
+ ["==================== UNSUPPORTED NODE.JS VERSION ===================="]);
+ t.deepEqual(processStderrWriteStub.getCall(2).args,
+ ["You are using an unsupported version of Node.js"]);
+ t.deepEqual(processStderrWriteStub.getCall(4).args,
+ [`Detected version v10.0.0 but ui5-cli-engines-test requires ^999`]);
+ t.deepEqual(processStderrWriteStub.getCall(5).args, ["\n\n"]);
+ t.deepEqual(processStderrWriteStub.getCall(6).args,
+ ["=> Please upgrade to a supported version of Node.js to use this tool"]);
+ t.deepEqual(processStderrWriteStub.getCall(8).args,
+ ["====================================================================="]);
+});
+
+test.serial("checkRequirements: logs warning when using pre-release Node.js version", (t) => {
+ const {processStderrWriteStub} = t.context;
+
+ const {checkRequirements} = require("../../bin/ui5.cjs");
+
+ const returnValue = checkRequirements({
+ pkg: {
+ name: "ui5-cli-engines-test",
+ engines: {
+ node: "^17"
+ }
+ },
+ nodeVersion: "v17.0.0-v8-canary202108258414d1aed8"
+ });
+
+ t.true(returnValue);
+ t.is(processStderrWriteStub.callCount, 16, "console.log should be called 16 times");
+
+ t.is(processStderrWriteStub.getCall(0).args[0],
+ "====================== UNSTABLE NODE.JS VERSION =====================");
+ t.is(processStderrWriteStub.getCall(2).args[0],
+ "You are using an unstable version of Node.js");
+ t.is(processStderrWriteStub.getCall(4).args[0],
+ "Detected Node.js version v17.0.0-v8-canary202108258414d1aed8");
+ t.is(processStderrWriteStub.getCall(5).args[0], "\n\n");
+ t.is(processStderrWriteStub.getCall(6).args[0],
+ "=> Please note that an unstable version might cause unexpected");
+ t.is(processStderrWriteStub.getCall(8).args[0],
+ " behavior. For productive use please consider using a stable");
+ t.is(processStderrWriteStub.getCall(10).args[0],
+ " version of Node.js! For the release policy of Node.js, see");
+ t.is(processStderrWriteStub.getCall(12).args[0],
+ " https://nodejs.org/en/about/releases");
+ t.is(processStderrWriteStub.getCall(14).args[0],
+ "=====================================================================");
+});
+
+test.serial("invokeLocalInstallation: Invokes local installation when found", async (t) => {
+ const {processStdoutWriteStub} = t.context;
+
+ importLocalStub.returns({});
+
+ const {invokeLocalInstallation} = require("../../bin/ui5.cjs");
+
+ const returnValue = await invokeLocalInstallation({name: "ui5-cli-test"});
+
+ t.true(returnValue);
+
+ t.is(processStdoutWriteStub.callCount, 2, "Information messages should be provided");
+
+ t.deepEqual(processStdoutWriteStub.getCall(0).args, ["INFO: Using local ui5-cli-test installation"]);
+ t.deepEqual(processStdoutWriteStub.getCall(1).args, ["\n\n"]);
+
+ t.is(importLocalStub.callCount, 1, "import-local should be called once");
+ t.is(importLocalStub.getCall(0).args.length, 1);
+ const importLocaPath = importLocalStub.getCall(0).args[0];
+ t.is(importLocaPath, fileURLToPath(new URL("../../bin/ui5.cjs", import.meta.url)),
+ "import-local should be called with bin/ui5.cjs filename");
+});
+
+test.serial("invokeLocalInstallation: Invokes local installation when found (/w --verbose)", async (t) => {
+ const {processStderrWriteStub} = t.context;
+
+ importLocalStub.returns({});
+
+ // Enable verbose logging
+ process.argv = [...process.argv, "--verbose"];
+
+ const {invokeLocalInstallation} = require("../../bin/ui5.cjs");
+
+ const returnValue = await invokeLocalInstallation({name: "ui5-cli-test"});
+
+ t.true(returnValue);
+
+ t.is(processStderrWriteStub.callCount, 4, "console.info should be called 3 times");
+
+ t.deepEqual(processStderrWriteStub.getCall(0).args, [
+ "INFO: This project contains an individual ui5-cli-test installation which " +
+ "will be used over the global one."]);
+ t.deepEqual(processStderrWriteStub.getCall(2).args, [
+ "See https://github.com/SAP/ui5-cli#local-vs-global-installation for details."
+ ]);
+ t.deepEqual(processStderrWriteStub.getCall(3).args, ["\n\n"]);
+
+ t.is(importLocalStub.callCount, 1, "import-local should be called once");
+ t.is(importLocalStub.getCall(0).args.length, 1);
+ const importLocaPath = importLocalStub.getCall(0).args[0];
+ t.is(importLocaPath, fileURLToPath(new URL("../../bin/ui5.cjs", import.meta.url)),
+ "import-local should be called with bin/ui5.cjs filename");
+});
+
+test.serial("invokeLocalInstallation: Doesn't invoke local installation when UI5_CLI_NO_LOCAL is set", async (t) => {
+ const {processStderrWriteStub} = t.context;
+
+ process.env.UI5_CLI_NO_LOCAL = "true";
+
+ const {invokeLocalInstallation} = require("../../bin/ui5.cjs");
+
+ const returnValue = await invokeLocalInstallation({name: "ui5-cli-test"});
+
+ t.false(returnValue);
+
+ t.is(processStderrWriteStub.callCount, 0, "Information messages should be provided");
+
+ t.is(importLocalStub.callCount, 0, "import-local should not be called");
+});
+
+test.serial("invokeLocalInstallation: Doesn't invoke local installation when it is not found", async (t) => {
+ const {processStderrWriteStub} = t.context;
+
+ importLocalStub.returns(undefined);
+
+ const {invokeLocalInstallation} = require("../../bin/ui5.cjs");
+
+ const returnValue = await invokeLocalInstallation({name: "ui5-cli-test"});
+
+ t.false(returnValue);
+
+ t.is(processStderrWriteStub.callCount, 0, "stderr info should not be provided");
+
+ t.is(importLocalStub.callCount, 2, "import-local should be called twice (ui5.cjs and ui5.js)");
+ t.deepEqual(importLocalStub.getCall(0).args, [fileURLToPath(new URL("../../bin/ui5.cjs", import.meta.url))],
+ "import-local should be called with bin/ui5.cjs filename");
+ t.deepEqual(importLocalStub.getCall(1).args, [fileURLToPath(new URL("../../bin/ui5.js", import.meta.url))],
+ "import-local should be called with bin/ui5.js filename");
+});
+
+test.serial("main (unsupported Node.js version)", async (t) => {
+ const {sinon, processStderrWriteStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ const ui5 = require("../../bin/ui5.cjs");
+ const {main} = ui5;
+
+ sinon.stub(ui5, "checkRequirements").returns(false);
+ sinon.stub(ui5, "invokeLocalInstallation");
+ sinon.stub(ui5, "invokeCLI");
+
+ await main();
+
+ const errorCode = await processExit;
+ t.is(errorCode, 1);
+
+ t.is(processStderrWriteStub.callCount, 0);
+
+ t.is(ui5.checkRequirements.callCount, 1);
+ t.is(ui5.invokeLocalInstallation.callCount, 0);
+ t.is(ui5.invokeCLI.callCount, 0);
+});
+
+test.serial("main (invocation of local installation)", async (t) => {
+ const {sinon, processStderrWriteStub} = t.context;
+
+ const processExitStub = sinon.stub(process, "exit");
+
+ const ui5 = require("../../bin/ui5.cjs");
+ const {main} = ui5;
+
+ sinon.stub(ui5, "invokeLocalInstallation").resolves(true);
+ sinon.stub(ui5, "invokeCLI");
+
+ await main();
+
+ t.is(processExitStub.callCount, 0);
+ t.is(processStderrWriteStub.callCount, 0);
+
+ t.is(ui5.invokeLocalInstallation.callCount, 1);
+ t.is(ui5.invokeCLI.callCount, 0);
+});
+
+test.serial("integration: main / invokeCLI", async (t) => {
+ // It seems to be impossible to mock/stub dynamic imports of ES modules
+ // The require.cache is not taken into account and esmock doesn't work (as of v2.0.7)
+
+ // Therefore this test is an integration test that really invokes the CLI / yargs to
+ // fail with an unknown command error
+
+ const {sinon, processStderrWriteStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ process.argv = [...process.argv, "foo", "--no-update-notifier"];
+
+ const {main} = require("../../bin/ui5.cjs");
+
+ await main();
+
+ const errorCode = await processExit;
+ t.is(errorCode, 1);
+
+ t.is(processStderrWriteStub.callCount, 6);
+
+ t.deepEqual(processStderrWriteStub.getCall(0).args, [chalk.bold.yellow("Command Failed:")], "Correct error log");
+ t.deepEqual(processStderrWriteStub.getCall(2).args, ["Unknown argument: foo"], "Correct error log");
+});
+
+test.serial("integration: Executing main when required as main module", async (t) => {
+ const {sinon, processStderrWriteStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ process.env.UI5_CLI_TEST_BIN_RUN_MAIN = "true";
+
+ process.argv = [...process.argv, "foo", "--no-update-notifier"];
+
+ require("../../bin/ui5.cjs");
+
+ const errorCode = await processExit;
+ t.is(errorCode, 1);
+
+ t.is(processStderrWriteStub.callCount, 6);
+
+ t.deepEqual(processStderrWriteStub.getCall(0).args, [chalk.bold.yellow("Command Failed:")], "Correct error log");
+ t.deepEqual(processStderrWriteStub.getCall(2).args, ["Unknown argument: foo"], "Correct error log");
+});
+
+test.serial("integration: Executing main when required as main module (catch initialize error)", async (t) => {
+ const {sinon, processStderrWriteStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ process.env.UI5_CLI_TEST_BIN_RUN_MAIN = "true";
+
+ process.argv = [...process.argv, "foo"];
+
+ const ui5 = require("../../bin/ui5.cjs");
+ // Immediately overwrite invokeCLI function before it is called
+ ui5.invokeCLI = async () => {
+ throw new Error("TEST: Unable to invoke CLI");
+ };
+
+ const errorCode = await processExit;
+ t.is(errorCode, 1);
+
+ t.is(processStderrWriteStub.callCount, 3);
+
+ t.deepEqual(processStderrWriteStub.getCall(0).args, ["Fatal Error: Unable to initialize UI5 CLI"]);
+ t.is(processStderrWriteStub.getCall(2).args.length, 1);
+ t.true(processStderrWriteStub.getCall(2).args[0] instanceof Error);
+ t.is(processStderrWriteStub.getCall(2).args[0].message, "TEST: Unable to invoke CLI");
+});
diff --git a/packages/cli/test/e2e/Dockerfile b/packages/cli/test/e2e/Dockerfile
new file mode 100644
index 00000000000..dd829e2a265
--- /dev/null
+++ b/packages/cli/test/e2e/Dockerfile
@@ -0,0 +1,10 @@
+FROM node:current-slim
+
+WORKDIR /home/node/e2e/ui5-cli
+
+COPY . .
+RUN test/e2e/npm-pack-production.sh
+
+WORKDIR /home/node/e2e/test
+
+CMD ["/bin/bash", "/home/node/e2e/ui5-cli/test/e2e/test.sh"]
diff --git a/packages/cli/test/e2e/build-image.sh b/packages/cli/test/e2e/build-image.sh
new file mode 100755
index 00000000000..49ed8b74926
--- /dev/null
+++ b/packages/cli/test/e2e/build-image.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -e
+
+cd "$(dirname -- "$0")/../../"
+echo "Changed directory to $(pwd)"
+
+echo "Building image..."
+docker build -t sap/ui5-cli/e2e-test -f test/e2e/Dockerfile .
+echo "Done building image."
+
+exit 0
diff --git a/packages/cli/test/e2e/npm-pack-production.sh b/packages/cli/test/e2e/npm-pack-production.sh
new file mode 100755
index 00000000000..b6aeb7031d9
--- /dev/null
+++ b/packages/cli/test/e2e/npm-pack-production.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+set -e
+
+# In npm 8 "npm prune" doesn't work as expected
+echo "Creating backup of package.json"
+mv package.json package.json.bak
+
+echo "Removing devDependencies from package.json"
+node <<- EOM
+ const fs = require("fs");
+ const pkg = JSON.parse(fs.readFileSync("package.json.bak", {encoding: "utf8"}));
+ pkg.devDependencies = {};
+ fs.writeFileSync("package.json", JSON.stringify(pkg, null, "\t"), {encoding: "utf8"});
+EOM
+
+echo "Pruning devDependencies..."
+npm prune --omit=dev
+
+echo "Updating npm-shrinkwrap.json..."
+npm shrinkwrap
+
+echo "Restoring original package.json"
+rm package.json
+mv package.json.bak package.json
+
+echo "Creating npm package for local installation..."
+npm pack
diff --git a/packages/cli/test/e2e/run-image.sh b/packages/cli/test/e2e/run-image.sh
new file mode 100755
index 00000000000..f980754114b
--- /dev/null
+++ b/packages/cli/test/e2e/run-image.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -e
+
+cd "$(dirname -- "$0")/../../"
+echo "Changed directory to $(pwd)"
+
+docker run --rm sap/ui5-cli/e2e-test
diff --git a/packages/cli/test/e2e/test.sh b/packages/cli/test/e2e/test.sh
new file mode 100755
index 00000000000..f4ca4c5d14d
--- /dev/null
+++ b/packages/cli/test/e2e/test.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+set -e
+
+VERSION=$(node -e 'process.stdout.write(require("/home/node/e2e/ui5-cli/package.json").version)')
+CLI_PACKAGE="/home/node/e2e/ui5-cli/ui5-cli-$VERSION.tgz"
+
+# Install CLI globally
+echo "Installing @ui5/cli v$VERSION globally..."
+npm i -g "$CLI_PACKAGE"
+
+echo "Creating test application project..."
+mkdir application && cd application
+npm init --yes
+
+echo "ui5 --version"
+ui5 --version
+
+echo "ui5 versions"
+ui5 versions
+
+echo "Creating webapp folder..."
+mkdir -p webapp
+
+echo ""
+echo "Creating dummy webapp/manifest.json file..."
+echo "{ \"sap.app\": { \"id\": \"ui5.cli.e2e.test.application\" } }" > webapp/manifest.json
+
+echo ""
+echo "Initializing ui5 project..."
+ui5 init
+
+echo "Adding @ui5/cli v$VERSION as project devDependency..."
+npm i -D "$CLI_PACKAGE"
+
+echo ""
+echo "Invoking local installation via global command..."
+LOCAL_UI5_VERSION=$(ui5 --version)
+echo "$LOCAL_UI5_VERSION"
+
+EXPECTED_BIN_PATH=$(node -e 'process.stdout.write(require.resolve("@ui5/cli/bin/ui5.js"))')
+EXPECTED_LOCAL_UI5_VERSION="INFO: Using local @ui5/cli installation
+
+$VERSION (from $EXPECTED_BIN_PATH)"
+
+if [ "$LOCAL_UI5_VERSION" != "$EXPECTED_LOCAL_UI5_VERSION" ]; then
+ echo ""
+ echo "ERROR: Failed to invoke local installation"
+ echo "Expected output:"
+ echo "$EXPECTED_LOCAL_UI5_VERSION"
+ exit 1
+fi
diff --git a/packages/cli/test/fixtures/@ui5/builder/index.js b/packages/cli/test/fixtures/@ui5/builder/index.js
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/@ui5/builder/package.json b/packages/cli/test/fixtures/@ui5/builder/package.json
new file mode 100644
index 00000000000..e93ddd3622e
--- /dev/null
+++ b/packages/cli/test/fixtures/@ui5/builder/package.json
@@ -0,0 +1,5 @@
+{
+ "version": "0.2.6",
+ "type": "module",
+ "exports": "./index.js"
+}
diff --git a/packages/cli/test/fixtures/@ui5/fs/index.js b/packages/cli/test/fixtures/@ui5/fs/index.js
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/@ui5/fs/package.json b/packages/cli/test/fixtures/@ui5/fs/package.json
new file mode 100644
index 00000000000..5405315b750
--- /dev/null
+++ b/packages/cli/test/fixtures/@ui5/fs/package.json
@@ -0,0 +1,5 @@
+{
+ "version": "0.2.0",
+ "type": "module",
+ "exports": "./index.js"
+}
diff --git a/packages/cli/test/fixtures/@ui5/logger/index.js b/packages/cli/test/fixtures/@ui5/logger/index.js
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/@ui5/logger/package.json b/packages/cli/test/fixtures/@ui5/logger/package.json
new file mode 100644
index 00000000000..176d5a9ca35
--- /dev/null
+++ b/packages/cli/test/fixtures/@ui5/logger/package.json
@@ -0,0 +1,5 @@
+{
+ "version": "0.2.2",
+ "type": "module",
+ "exports": "./index.js"
+}
diff --git a/packages/cli/test/fixtures/@ui5/project/index.js b/packages/cli/test/fixtures/@ui5/project/index.js
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/@ui5/project/package.json b/packages/cli/test/fixtures/@ui5/project/package.json
new file mode 100644
index 00000000000..fe902d50733
--- /dev/null
+++ b/packages/cli/test/fixtures/@ui5/project/package.json
@@ -0,0 +1,5 @@
+{
+ "version": "0.2.3",
+ "type": "module",
+ "exports": "./index.js"
+}
diff --git a/packages/cli/test/fixtures/@ui5/server/index.js b/packages/cli/test/fixtures/@ui5/server/index.js
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/@ui5/server/package.json b/packages/cli/test/fixtures/@ui5/server/package.json
new file mode 100644
index 00000000000..176d5a9ca35
--- /dev/null
+++ b/packages/cli/test/fixtures/@ui5/server/package.json
@@ -0,0 +1,5 @@
+{
+ "version": "0.2.2",
+ "type": "module",
+ "exports": "./index.js"
+}
diff --git a/packages/cli/test/fixtures/init/application/package.json b/packages/cli/test/fixtures/init/application/package.json
new file mode 100644
index 00000000000..63696d06cbd
--- /dev/null
+++ b/packages/cli/test/fixtures/init/application/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-application",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/application/ui5.yaml b/packages/cli/test/fixtures/init/application/ui5.yaml
new file mode 100644
index 00000000000..9df145b256f
--- /dev/null
+++ b/packages/cli/test/fixtures/init/application/ui5.yaml
@@ -0,0 +1,4 @@
+specVersion: "0.1"
+metadata:
+ name: sample-app
+type: application
diff --git a/packages/cli/test/fixtures/init/application/webapp/.gitkeep b/packages/cli/test/fixtures/init/application/webapp/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-missing-package-name/package.json b/packages/cli/test/fixtures/init/invalid-missing-package-name/package.json
new file mode 100644
index 00000000000..11d1353a5e7
--- /dev/null
+++ b/packages/cli/test/fixtures/init/invalid-missing-package-name/package.json
@@ -0,0 +1,11 @@
+{
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/invalid-missing-package-name/webapp/.gitkeep b/packages/cli/test/fixtures/init/invalid-missing-package-name/webapp/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-no-package-json/webapp/.gitkeep b/packages/cli/test/fixtures/init/invalid-no-package-json/webapp/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-test/package.json b/packages/cli/test/fixtures/init/invalid-test/package.json
new file mode 100644
index 00000000000..a9eff2a7949
--- /dev/null
+++ b/packages/cli/test/fixtures/init/invalid-test/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-invalid",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/invalid-test/test/.gitkeep b/packages/cli/test/fixtures/init/invalid-test/test/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src-test/package.json b/packages/cli/test/fixtures/init/invalid-webapp-src-test/package.json
new file mode 100644
index 00000000000..a9eff2a7949
--- /dev/null
+++ b/packages/cli/test/fixtures/init/invalid-webapp-src-test/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-invalid",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src-test/src/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-src-test/src/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src-test/test/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-src-test/test/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src-test/webapp/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-src-test/webapp/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src/package.json b/packages/cli/test/fixtures/init/invalid-webapp-src/package.json
new file mode 100644
index 00000000000..a9eff2a7949
--- /dev/null
+++ b/packages/cli/test/fixtures/init/invalid-webapp-src/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-invalid",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src/src/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-src/src/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-src/webapp/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-src/webapp/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-test/package.json b/packages/cli/test/fixtures/init/invalid-webapp-test/package.json
new file mode 100644
index 00000000000..a9eff2a7949
--- /dev/null
+++ b/packages/cli/test/fixtures/init/invalid-webapp-test/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-invalid",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-test/test/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-test/test/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid-webapp-test/webapp/.gitkeep b/packages/cli/test/fixtures/init/invalid-webapp-test/webapp/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/invalid/package.json b/packages/cli/test/fixtures/init/invalid/package.json
new file mode 100644
index 00000000000..a9eff2a7949
--- /dev/null
+++ b/packages/cli/test/fixtures/init/invalid/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-invalid",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/library/package.json b/packages/cli/test/fixtures/init/library/package.json
new file mode 100644
index 00000000000..5037d8cbea4
--- /dev/null
+++ b/packages/cli/test/fixtures/init/library/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "init-library",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "UNLICENSED"
+}
diff --git a/packages/cli/test/fixtures/init/library/src/.gitkeep b/packages/cli/test/fixtures/init/library/src/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/fixtures/init/library/test/.gitkeep b/packages/cli/test/fixtures/init/library/test/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/cli/test/lib/cli/base.js b/packages/cli/test/lib/cli/base.js
new file mode 100644
index 00000000000..8534a3a2ce3
--- /dev/null
+++ b/packages/cli/test/lib/cli/base.js
@@ -0,0 +1,306 @@
+import test from "ava";
+import path from "node:path";
+import {execa} from "execa";
+import sinon from "sinon";
+import esmock from "esmock";
+import chalk from "chalk";
+import stripAnsi from "strip-ansi";
+import yargs from "yargs";
+import {readFileSync} from "node:fs";
+
+const pkgJsonPath = new URL("../../../package.json", import.meta.url);
+const pkg = JSON.parse(readFileSync(pkgJsonPath));
+const __dirname = import.meta.dirname;
+const ui5Cli = path.join(__dirname, "..", "..", "..", "bin", "ui5.cjs");
+const ui5 = (args, options = {}) => execa(ui5Cli, args, options);
+
+test.beforeEach(async (t) => {
+ t.context.consoleLogStub = sinon.stub(process.stderr, "write");
+
+ t.context.isLogLevelEnabledStub = sinon.stub();
+ t.context.isLogLevelEnabledStub.withArgs("error").returns(true);
+ t.context.isLogLevelEnabledStub.withArgs("verbose").returns(false);
+ t.context.consoleWriterStopStub = sinon.stub();
+
+ t.context.base = await esmock("../../../lib/cli/base.js", {
+ "@ui5/logger": {
+ isLogLevelEnabled: t.context.isLogLevelEnabledStub
+ },
+ "@ui5/logger/writers/Console": {
+ stop: t.context.consoleWriterStopStub
+ }
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+});
+
+test.serial("ui5 --version", async (t) => {
+ const {stdout} = await ui5(["--version"]);
+ t.is(stdout, `${pkg.version} (from ${ui5Cli})`);
+});
+
+test.serial("ui5 -v", async (t) => {
+ const {stdout} = await ui5(["-v"]);
+ t.is(stdout, `${pkg.version} (from ${ui5Cli})`);
+});
+
+test.serial("Handle multiple options", async (t) => {
+ const {stderr} = await ui5(["versions", "--log-level", "silent", "--log-level", "silly"]);
+ t.regex(stripAnsi(stderr), /verb/g, "Verbose logging got enabled");
+});
+
+test.serial("Yargs error handling", async (t) => {
+ const {consoleLogStub, consoleWriterStopStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ const {default: base} = await import("../../../lib/cli/base.js");
+
+ const cli = yargs();
+
+ base(cli);
+
+ cli.command({
+ command: "foo",
+ describe: "This is a task",
+ handler: async function() {}
+ });
+
+ await cli.parseAsync(["invalid"]);
+
+ const errorCode = await processExit;
+
+ t.is(errorCode, 1, "Should exit with error code 1");
+ t.is(consoleWriterStopStub.callCount, 0, "ConsoleWriter.stop did not get called");
+ t.is(consoleLogStub.callCount, 6);
+ t.deepEqual(consoleLogStub.getCall(0).args, [chalk.bold.yellow("Command Failed:")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(2).args, ["Unknown argument: invalid"], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(3).args, ["\n\n"], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(4).args, [
+ chalk.dim(`See 'ui5 --help'`)
+ ], "Correct error log");
+});
+
+
+test.serial("Exception error handling", async (t) => {
+ const {base, consoleLogStub, consoleWriterStopStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ const cli = yargs();
+
+ base(cli);
+
+ const error = new Error("Some error from foo command");
+
+ cli.command({
+ command: "foo",
+ describe: "This task fails with an error",
+ handler: async function() {
+ throw error;
+ }
+ });
+
+ await t.throwsAsync(cli.parse(["foo"]), {
+ is: error
+ });
+
+ const errorCode = await processExit;
+
+ t.is(errorCode, 1, "Should exit with error code 1");
+ t.is(consoleWriterStopStub.callCount, 1, "ConsoleWriter.stop got called once");
+ t.is(consoleLogStub.callCount, 10);
+ t.deepEqual(consoleLogStub.getCall(1).args, [chalk.bold.red("⚠️ Process Failed With Error")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(3).args, [chalk.underline("Error Message:")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(5).args,
+ ["Some error from foo command"], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(8).args, [chalk.dim(
+ `For details, execute the same command again with an additional '--verbose' parameter`)], "Correct error log");
+});
+
+test.serial("Exception error handling without logging (silent)", async (t) => {
+ const {base, consoleLogStub, isLogLevelEnabledStub, consoleWriterStopStub} = t.context;
+
+ isLogLevelEnabledStub.withArgs("error").returns(false);
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ const cli = yargs();
+
+ base(cli);
+
+ const error = new Error("Some error from foo command");
+
+ cli.command({
+ command: "foo",
+ describe: "This task fails with an error",
+ handler: async function() {
+ throw error;
+ }
+ });
+
+ await t.throwsAsync(cli.parse(["foo"]), {
+ is: error
+ });
+
+ const errorCode = await processExit;
+
+ t.is(errorCode, 1, "Should exit with error code 1");
+ t.is(consoleWriterStopStub.callCount, 1, "ConsoleWriter.stop got called once");
+ t.is(consoleLogStub.callCount, 0);
+});
+
+test.serial("Exception error handling with verbose logging", async (t) => {
+ const {base, consoleLogStub, isLogLevelEnabledStub} = t.context;
+
+ isLogLevelEnabledStub.withArgs("verbose").returns(true);
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ const cli = yargs();
+
+ base(cli);
+
+ const error = new Error("Some error from foo command");
+
+ cli.command({
+ command: "foo",
+ describe: "This task fails with an error",
+ handler: async function() {
+ throw error;
+ }
+ });
+
+ await t.throwsAsync(cli.parse(["foo"]), {
+ is: error
+ });
+
+ const errorCode = await processExit;
+
+ t.is(errorCode, 1, "Should exit with error code 1");
+ t.is(consoleLogStub.callCount, 14);
+ t.deepEqual(consoleLogStub.getCall(1).args, [chalk.bold.red("⚠️ Process Failed With Error")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(3).args, [chalk.underline("Error Message:")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(5).args,
+ ["Some error from foo command"], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(8).args, [chalk.underline("Stack Trace:")], "Correct error log");
+ t.is(consoleLogStub.getCall(10).args.length, 1);
+ t.true(consoleLogStub.getCall(10).args[0]
+ .startsWith("Error: Some error from foo command"), "Correct error log");
+
+ t.deepEqual(consoleLogStub.getCall(consoleLogStub.callCount - 2).args,
+ [chalk.dim(
+ `If you think this is an issue of the UI5 CLI, you might report it using the ` +
+ `following URL: `) +
+ chalk.dim.bold.underline(`https://github.com/UI5/cli/issues/new/choose`)],
+ "Correct last log line");
+});
+
+test.serial("Unexpected error handling", async (t) => {
+ const {consoleLogStub, consoleWriterStopStub} = t.context;
+
+ const processExit = new Promise((resolve) => {
+ const processExitStub = sinon.stub(process, "exit");
+ processExitStub.callsFake((errorCode) => {
+ processExitStub.restore();
+ resolve(errorCode);
+ });
+ });
+
+ const {default: base} = await import("../../../lib/cli/base.js");
+
+ const cli = yargs();
+
+ base(cli);
+
+ const typeError = new TypeError("Cannot do this");
+
+ cli.command({
+ command: "foo",
+ describe: "This task fails with a TypeError",
+ handler: async function() {
+ throw typeError;
+ }
+ });
+
+ await t.throwsAsync(cli.parse(["foo"]), {
+ is: typeError
+ });
+
+ const errorCode = await processExit;
+
+ t.is(errorCode, 1, "Should exit with error code 1");
+ t.is(consoleWriterStopStub.callCount, 0, "ConsoleWriter.stop did not get called");
+ t.is(consoleLogStub.callCount, 14);
+ t.deepEqual(consoleLogStub.getCall(1).args, [chalk.bold.red("⚠️ Process Failed With Error")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(3).args, [chalk.underline("Error Message:")], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(5).args,
+ ["Cannot do this"], "Correct error log");
+ t.deepEqual(consoleLogStub.getCall(8).args, [chalk.underline("Stack Trace:")], "Correct error log");
+ t.is(consoleLogStub.getCall(10).args.length, 1);
+ t.true(consoleLogStub.getCall(10).args[0]
+ .startsWith("TypeError: Cannot do this"), "Correct error log");
+
+ t.deepEqual(consoleLogStub.getCall(consoleLogStub.callCount - 2).args,
+ [chalk.dim(
+ `If you think this is an issue of the UI5 CLI, you might report it using the ` +
+ `following URL: `) +
+ chalk.dim.bold.underline(`https://github.com/UI5/cli/issues/new/choose`)],
+ "Correct last log line");
+});
+
+test.serial("ui5 --no-update-notifier", async (t) => {
+ const {stdout, failed} = await ui5(["versions", "--no-update-notifier"]);
+ t.regex(stdout, /@ui5\/cli:/, "Output includes version information");
+ t.false(failed, "Command should not fail");
+});
+
+test.serial("ui5 --output-style", async (t) => {
+ await t.throwsAsync(ui5(["build", "--output-style", "nonExistent"]), {
+ message: /Argument: output-style, Given: "Nonexistent", Choices: "Default", "Flat", "Namespace"/s
+ }, "Coercion correctly capitalizes the first letter and makes the rest lowercase");
+
+
+ // "--output-style" uses a coerce to transform the input into the correct letter case.
+ // It is hard/unmaintainable to spy on internal implementation, so we check the output.
+ // The coerce goes before the real ui5 build, so we just need to check whether
+ // an invalid "--output-style" choice exception is not thrown.
+ // Of course, the build would throw another exception, because there's nothing actually to build.
+ await t.throwsAsync(ui5(["build", "--output-style", "flat"]), {
+ message: /^((?!Argument: output-style, Given: "Flat).)*$/s
+ }, "Does not throw an exception because of the --output-style input");
+
+ await t.throwsAsync(ui5(["build", "--output-style", "nAmEsPaCe"]), {
+ message: /^((?!Argument: output-style, Given: "Namespace).)*$/s
+ }, "Does not throw an exception because of the --output-style input");
+
+ await t.throwsAsync(ui5(["build", "--output-style", "Default"]), {
+ message: /^((?!Argument: output-style, Given: "Default).)*$/s
+ }, "Does not throw an exception because of the --output-style input");
+});
diff --git a/packages/cli/test/lib/cli/cli.js b/packages/cli/test/lib/cli/cli.js
new file mode 100644
index 00000000000..c6718bc0ed2
--- /dev/null
+++ b/packages/cli/test/lib/cli/cli.js
@@ -0,0 +1,165 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import {fileURLToPath} from "node:url";
+
+test.beforeEach(async (t) => {
+ t.context.originalNodeEnv = process.env.NODE_ENV;
+
+ t.context.updateNotifierNotify = sinon.stub();
+ t.context.updateNotifier = sinon.stub().returns({
+ notify: t.context.updateNotifierNotify
+ }).named("updateNotifier");
+
+ t.context.argvGetter = sinon.stub();
+ t.context.yargsInstance = {
+ parserConfiguration: sinon.stub(),
+ version: sinon.stub(),
+ scriptName: sinon.stub(),
+ command: sinon.stub(),
+ terminalWidth: sinon.stub().returns(123),
+ wrap: sinon.stub(),
+ get argv() {
+ t.context.argvGetter();
+ return undefined;
+ }
+ };
+
+ t.context.yargs = sinon.stub().returns(t.context.yargsInstance).named("yargs");
+
+ t.context.setVersion = sinon.stub().named("setVersion");
+ t.context.cliBase = sinon.stub().named("cliBase");
+
+ t.context.readdir = sinon.stub().resolves([
+ {
+ isDirectory: sinon.stub().returns(false),
+ name: "build.js"
+ },
+ {
+ isDirectory: sinon.stub().returns(false),
+ name: "serve.js"
+ },
+ {
+ // Directory should be filtered out
+ isDirectory: sinon.stub().returns(true),
+ name: "someDir"
+ },
+ {
+ // Non-js files should be filtered out
+ isDirectory: sinon.stub().returns(false),
+ name: ".DS_Store"
+ }
+ ]);
+
+ t.context.cli = await esmock.p("../../../lib/cli/cli.js", {
+ "update-notifier": t.context.updateNotifier,
+ "yargs": t.context.yargs,
+ // TODO: Somehow esmock is unable to mock this import
+ // "yargs/helpers": {
+ // hideBin: t.context.yargsHideBin
+ // },
+ "../../../lib/cli/version.js": {
+ setVersion: t.context.setVersion
+ },
+ "../../../lib/cli/base.js": t.context.cliBase,
+ "node:fs/promises": {
+ readdir: t.context.readdir
+ },
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.cli);
+ process.env.NODE_ENV = t.context.originalNodeEnv;
+});
+
+test.serial("CLI", async (t) => {
+ const {
+ cli, updateNotifier, updateNotifierNotify, argvGetter, yargsInstance, yargs,
+ setVersion, cliBase
+ } = t.context;
+
+ const pkg = {
+ version: "0.0.0-test"
+ };
+
+ // Remove NODE_ENV=test to allow execution of update-notifier
+ delete process.env.NODE_ENV;
+
+ await cli(pkg);
+
+ t.is(updateNotifier.callCount, 1);
+ t.deepEqual(updateNotifier.getCall(0).args, [{pkg, shouldNotifyInNpmScript: true, updateCheckInterval: 86400000}]);
+
+ t.is(updateNotifierNotify.callCount, 1);
+ t.deepEqual(updateNotifierNotify.getCall(0).args, []);
+
+ t.is(yargs.callCount, 1);
+ t.deepEqual(yargs.getCall(0).args, [[]]);
+
+ t.is(yargsInstance.parserConfiguration.callCount, 1);
+ t.deepEqual(yargsInstance.parserConfiguration.getCall(0).args, [{
+ "parse-numbers": false
+ }]);
+
+ t.is(setVersion.callCount, 1);
+ t.deepEqual(setVersion.getCall(0).args, [
+ `0.0.0-test (from ${fileURLToPath(new URL("../../../bin/ui5.cjs", import.meta.url))})`
+ ]);
+
+ t.is(yargsInstance.version.callCount, 1);
+ t.deepEqual(yargsInstance.version.getCall(0).args, [
+ `0.0.0-test (from ${fileURLToPath(new URL("../../../bin/ui5.cjs", import.meta.url))})`
+ ]);
+
+ t.is(yargsInstance.scriptName.callCount, 1);
+ t.deepEqual(yargsInstance.scriptName.getCall(0).args, ["ui5"]);
+
+ t.is(cliBase.callCount, 1);
+ t.deepEqual(cliBase.getCall(0).args, [yargsInstance]);
+
+ t.is(yargsInstance.command.callCount, 2);
+ t.is(yargsInstance.command.getCall(0).args.length, 1);
+ t.is(yargsInstance.command.getCall(0).args[0].command, "build");
+ t.is(yargsInstance.command.getCall(1).args.length, 1);
+ t.is(yargsInstance.command.getCall(1).args[0].command, "serve");
+
+ t.is(yargsInstance.terminalWidth.callCount, 1);
+ t.deepEqual(yargsInstance.terminalWidth.getCall(0).args, []);
+
+ t.is(yargsInstance.wrap.callCount, 1);
+ t.deepEqual(yargsInstance.wrap.getCall(0).args, [123]);
+
+ t.is(argvGetter.callCount, 1);
+ t.deepEqual(argvGetter.getCall(0).args, []);
+
+ sinon.assert.callOrder(
+ updateNotifier,
+ updateNotifierNotify,
+ yargs,
+ yargsInstance.parserConfiguration,
+ setVersion,
+ yargsInstance.version,
+ yargsInstance.scriptName,
+ cliBase,
+ yargsInstance.command,
+ yargsInstance.terminalWidth,
+ yargsInstance.wrap,
+ argvGetter
+ );
+});
+
+test.serial("CLI (NODE_ENV=test disables update-notifier)", async (t) => {
+ const {
+ cli, updateNotifier
+ } = t.context;
+
+ const pkg = {
+ version: "0.0.0-test"
+ };
+
+ await cli(pkg);
+
+ t.is(updateNotifier.callCount, 0);
+});
diff --git a/packages/cli/test/lib/cli/commands/add.js b/packages/cli/test/lib/cli/commands/add.js
new file mode 100644
index 00000000000..2f22163e7cf
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/add.js
@@ -0,0 +1,187 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+async function createMock(t, yamlUpdated = true) {
+ t.context.frameworkAddStub = sinon.stub().resolves({yamlUpdated});
+ t.context.addCommand = await esmock.p("../../../../lib/cli/commands/add.js", {
+ "../../../../lib/framework/add.js": t.context.frameworkAddStub
+ });
+}
+
+async function assertAddHandler(t, {argv, expectedLibraries, expectedConsoleLog}) {
+ await createMock(t);
+ await t.context.addCommand.handler(argv);
+
+ t.is(t.context.frameworkAddStub.callCount, 1, "Add function should be called once");
+ t.deepEqual(t.context.frameworkAddStub.getCall(0).args, [
+ {
+ libraries: expectedLibraries,
+ projectGraphOptions: {
+ dependencyDefinition: undefined,
+ config: undefined
+ }
+ }],
+ "Add function should be called with expected args");
+
+ t.is(t.context.processStdoutStub.callCount, expectedConsoleLog.length,
+ "console.log should be called " + expectedConsoleLog.length + " times");
+ expectedConsoleLog.forEach((expectedLog, i) => {
+ t.deepEqual(t.context.processStdoutStub.getCall(i).args, [expectedLog],
+ "console.log should be called with expected string on call index " + i);
+ });
+}
+
+async function assertFailingAddHandler(t, {argv, expectedMessage}) {
+ await createMock(t);
+ const exception = await t.throwsAsync(t.context.addCommand.handler(argv));
+
+ t.is(exception.message, expectedMessage, "Add handler should throw expected error");
+ t.is(t.context.frameworkAddStub.callCount, 0, "Add function should not be called");
+}
+
+async function assertFailingYamlUpdateAddHandler(t, {argv, expectedMessage}) {
+ await createMock(t, false);
+ const exception = await t.throwsAsync(t.context.addCommand.handler(argv));
+
+ t.is(exception.message, expectedMessage, "Add handler should throw expected error");
+ t.is(t.context.frameworkAddStub.callCount, 1, "Add function should be called once");
+}
+
+test.beforeEach((t) => {
+ t.context.processStdoutStub = sinon.stub(process.stdout, "write");
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.addCommand);
+});
+
+test.serial("Accepts single library", async (t) => {
+ await assertAddHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1"]},
+ expectedLibraries: [{name: "sap.ui.lib1"}],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Added framework library sap.ui.lib1 as dependency",
+ "\n",
+ ]
+ });
+});
+
+test.serial("Accepts multiple libraries", async (t) => {
+ await assertAddHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib2"]},
+ expectedLibraries: [{name: "sap.ui.lib1"}, {name: "sap.ui.lib2"}],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Added framework libraries sap.ui.lib1 sap.ui.lib2 as dependencies",
+ "\n",
+ ]
+ });
+});
+
+test.serial("Accepts multiple libraries (--development)", async (t) => {
+ await assertAddHandler(t, {
+ argv: {
+ "framework-libraries": [
+ "sap.ui.lib1",
+ "sap.ui.lib2"
+ ],
+ "development": true
+ },
+ expectedLibraries: [
+ {
+ name: "sap.ui.lib1",
+ development: true
+ },
+ {
+ name: "sap.ui.lib2",
+ development: true
+ }
+ ],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Added framework libraries sap.ui.lib1 sap.ui.lib2 as development dependencies",
+ "\n"
+ ]
+ });
+});
+
+test.serial("Accepts multiple libraries (--optional)", async (t) => {
+ await assertAddHandler(t, {
+ argv: {
+ "framework-libraries": [
+ "sap.ui.lib1",
+ "sap.ui.lib2"
+ ],
+ "optional": true
+ },
+ expectedLibraries: [
+ {
+ name: "sap.ui.lib1",
+ optional: true
+ },
+ {
+ name: "sap.ui.lib2",
+ optional: true
+ }
+ ],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Added framework libraries sap.ui.lib1 sap.ui.lib2 as optional dependencies",
+ "\n"
+ ]
+ });
+});
+
+test.serial("Rejects when development and optional are true", async (t) => {
+ await assertFailingAddHandler(t, {
+ argv: {
+ "framework-libraries": ["sap.ui.lib1"],
+ "development": true,
+ "optional": true
+ },
+ expectedMessage: "Options 'development' and 'optional' cannot be combined"
+ });
+});
+
+test.serial("Rejects on empty framework-libraries", async (t) => {
+ await assertFailingAddHandler(t, {
+ argv: {"framework-libraries": ""},
+ expectedMessage: "Missing mandatory parameter framework-libraries"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (single library)", async (t) => {
+ await assertFailingYamlUpdateAddHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1"]},
+ expectedMessage: "Internal error while adding framework library sap.ui.lib1 to ui5.yaml"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (multiple libraries)", async (t) => {
+ await assertFailingYamlUpdateAddHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib2"]},
+ expectedMessage: "Internal error while adding framework libraries sap.ui.lib1 sap.ui.lib2 to ui5.yaml"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (single library; with config path)", async (t) => {
+ await assertFailingYamlUpdateAddHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1"], "config": "/path/to/ui5.yaml"},
+ expectedMessage: "Internal error while adding framework library sap.ui.lib1 to config at /path/to/ui5.yaml"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (multiple libraries; with config path)", async (t) => {
+ await assertFailingYamlUpdateAddHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib2"], "config": "/path/to/ui5.yaml"},
+ expectedMessage:
+ "Internal error while adding framework libraries sap.ui.lib1 sap.ui.lib2 to config at /path/to/ui5.yaml"
+ });
+});
diff --git a/packages/cli/test/lib/cli/commands/build.js b/packages/cli/test/lib/cli/commands/build.js
new file mode 100644
index 00000000000..ac36226cbf8
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/build.js
@@ -0,0 +1,380 @@
+import path from "node:path";
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+function getDefaultArgv() {
+ // This has been taken from the actual argv object yargs provides
+ return {
+ "_": ["build"],
+ "loglevel": "info",
+ "log-level": "info",
+ "logLevel": "info",
+ "perf": false,
+ "silent": false,
+ "include-all-dependencies": false,
+ "all": false,
+ "a": false,
+ "includeAllDependencies": false,
+ "create-build-manifest": false,
+ "createBuildManifest": false,
+ "dest": "./dist",
+ "clean-dest": false,
+ "cleanDest": false,
+ "experimental-css-variables": false,
+ "experimentalCssVariables": false,
+ "cache-mode": "Default",
+ "cacheMode": "Default",
+ "output-style": "Default",
+ "$0": "ui5"
+ };
+}
+
+function getDefaultBuilderArgs() {
+ return {
+ destPath: "./dist",
+ cleanDest: false,
+ dependencyIncludes: {
+ includeAllDependencies: false,
+ includeDependency: undefined,
+ includeDependencyRegExp: undefined,
+ includeDependencyTree: undefined,
+ excludeDependency: undefined,
+ excludeDependencyRegExp: undefined,
+ excludeDependencyTree: undefined,
+ defaultIncludeDependency: undefined,
+ defaultIncludeDependencyRegExp: undefined,
+ defaultIncludeDependencyTree: undefined
+ },
+ createBuildManifest: false,
+ selfContained: false,
+ jsdoc: false,
+ includedTasks: undefined,
+ excludedTasks: undefined,
+ cssVariables: false,
+ outputStyle: "Default"
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.argv = getDefaultArgv();
+ t.context.expectedBuilderArgs = getDefaultBuilderArgs();
+
+ t.context.builder = sinon.stub().resolves();
+ t.context.getBuilderSettings = sinon.stub().returns(undefined);
+ const fakeGraph = {
+ getRoot: sinon.stub().returns({
+ getBuilderSettings: t.context.getBuilderSettings
+ }),
+ build: t.context.builder
+ };
+ t.context.expectedBuilderArgs.graph = fakeGraph;
+ t.context.ProjectGraphStub = sinon.stub().resolves(fakeGraph);
+ t.context.graphFromPackageDependenciesStub = sinon.stub().resolves(fakeGraph);
+ t.context.graphFromStaticFileStub = sinon.stub().resolves(fakeGraph);
+
+ t.context.build = await esmock.p("../../../../lib/cli/commands/build.js", {
+ "@ui5/project/graph": {
+ graphFromPackageDependencies: t.context.graphFromPackageDependenciesStub,
+ graphFromStaticFile: t.context.graphFromStaticFileStub
+ },
+ "@ui5/project/graph/ProjectGraph": t.context.ProjectGraphStub
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.build);
+});
+
+test.serial("ui5 build (default) ", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ await build.handler(argv);
+
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs, "default build triggered with expected arguments");
+});
+
+test.serial("ui5 build self-contained", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ argv._.push("self-contained");
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.selfContained = true;
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs, "Self-contained build called with expected arguments");
+});
+
+test.serial("ui5 build jsdoc", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ argv._.push("jsdoc");
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.jsdoc = true;
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs, "JSDoc build called with expected arguments");
+});
+
+test.serial("ui5 build --framework-version", async (t) => {
+ const {build, argv, graphFromPackageDependenciesStub} = t.context;
+
+ argv.frameworkVersion = "1.99.0";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromPackageDependenciesStub.getCall(0).args[0],
+ {
+ rootConfigPath: undefined,
+ versionOverride: "1.99.0",
+ workspaceConfigPath: undefined,
+ workspaceName: undefined,
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromPackageDependencies got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --cache-mode", async (t) => {
+ const {build, argv, graphFromPackageDependenciesStub} = t.context;
+
+ argv.cacheMode = "Off";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromPackageDependenciesStub.getCall(0).args[0],
+ {
+ rootConfigPath: undefined,
+ versionOverride: undefined,
+ workspaceConfigPath: undefined,
+ workspaceName: undefined,
+ cacheMode: "Off",
+ }, "generateProjectGraph.graphFromPackageDependencies got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --config", async (t) => {
+ const {build, argv, graphFromPackageDependenciesStub} = t.context;
+
+ argv.config = "ui5-test.yaml";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromPackageDependenciesStub.getCall(0).args[0],
+ {
+ rootConfigPath: "ui5-test.yaml",
+ versionOverride: undefined,
+ workspaceConfigPath: undefined,
+ workspaceName: undefined,
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromPackageDependencies got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --workspace", async (t) => {
+ const {build, argv, graphFromPackageDependenciesStub} = t.context;
+
+ argv.workspace = "dolphin";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromPackageDependenciesStub.getCall(0).args[0],
+ {
+ rootConfigPath: undefined,
+ versionOverride: undefined,
+ workspaceConfigPath: undefined,
+ workspaceName: "dolphin",
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromPackageDependencies got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --no-workspace", async (t) => {
+ const {build, argv, graphFromPackageDependenciesStub} = t.context;
+
+ argv.workspace = false;
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromPackageDependenciesStub.getCall(0).args[0],
+ {
+ rootConfigPath: undefined,
+ versionOverride: undefined,
+ workspaceConfigPath: undefined,
+ workspaceName: null,
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromPackageDependencies got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --workspace-config", async (t) => {
+ const {build, argv, graphFromPackageDependenciesStub} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "ui5-workspace.yaml");
+ argv.workspaceConfig = fakePath;
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromPackageDependenciesStub.getCall(0).args[0],
+ {
+ rootConfigPath: undefined,
+ versionOverride: undefined,
+ workspaceConfigPath: fakePath,
+ workspaceName: undefined,
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromPackageDependencies got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --dependency-definition", async (t) => {
+ const {build, argv, graphFromStaticFileStub} = t.context;
+
+ argv.dependencyDefinition = "dependencies.yaml";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromStaticFileStub.getCall(0).args[0],
+ {
+ filePath: "dependencies.yaml",
+ rootConfigPath: undefined,
+ versionOverride: undefined,
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromStaticFile got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --dependency-definition --config", async (t) => {
+ const {build, argv, graphFromStaticFileStub} = t.context;
+
+ argv.dependencyDefinition = "dependencies.yaml";
+ argv.config = "ui5-test.yaml";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromStaticFileStub.getCall(0).args[0],
+ {
+ filePath: "dependencies.yaml",
+ rootConfigPath: "ui5-test.yaml",
+ versionOverride: undefined,
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromStaticFile got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --dependency-definition --config --framework-version", async (t) => {
+ const {build, argv, graphFromStaticFileStub} = t.context;
+
+ argv.dependencyDefinition = "dependencies.yaml";
+ argv.config = "ui5-test.yaml";
+ argv.frameworkVersion = "1.99.0";
+
+ await build.handler(argv);
+
+ t.deepEqual(
+ graphFromStaticFileStub.getCall(0).args[0],
+ {
+ filePath: "dependencies.yaml",
+ rootConfigPath: "ui5-test.yaml",
+ versionOverride: "1.99.0",
+ cacheMode: "Default",
+ }, "generateProjectGraph.graphFromStaticFile got called with expected arguments"
+ );
+});
+
+test.serial("ui5 build --createBuildManifest", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ argv["create-build-manifest"] = true;
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.createBuildManifest = true;
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs, "default build triggered with expected arguments");
+});
+
+test.serial("ui5 build (Include/Exclude dependency options)", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ argv["include-dependency"] = ["sap.ui.core"];
+ argv["include-dependency-regexp"] = ["^sap.[mf]$"];
+ argv["include-dependency-tree"] = ["a"];
+ argv["exclude-dependency"] = ["sap.ui.layout"];
+ argv["exclude-dependency-regexp"] = ["^b0$"];
+ argv["exclude-dependency-tree"] = ["c1"];
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.dependencyIncludes = {
+ includeAllDependencies: false,
+ includeDependency: ["sap.ui.core"],
+ includeDependencyRegExp: ["^sap.[mf]$"],
+ includeDependencyTree: ["a"],
+ excludeDependency: ["sap.ui.layout"],
+ excludeDependencyRegExp: ["^b0$"],
+ excludeDependencyTree: ["c1"],
+ defaultIncludeDependency: undefined,
+ defaultIncludeDependencyRegExp: undefined,
+ defaultIncludeDependencyTree: undefined,
+ };
+
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs, "default build triggered with expected arguments");
+});
+
+test.serial("ui5 build (Include dependency via configuration)", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs, getBuilderSettings} = t.context;
+
+ getBuilderSettings.returns({
+ includeDependency: ["a"],
+ includeDependencyRegExp: ["^b0$"],
+ includeDependencyTree: ["b1"],
+ });
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.dependencyIncludes = {
+ includeAllDependencies: false,
+ includeDependency: undefined,
+ includeDependencyRegExp: undefined,
+ includeDependencyTree: undefined,
+ excludeDependency: undefined,
+ excludeDependencyRegExp: undefined,
+ excludeDependencyTree: undefined,
+ defaultIncludeDependency: ["a"],
+ defaultIncludeDependencyRegExp: ["^b0$"],
+ defaultIncludeDependencyTree: ["b1"]
+ };
+
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs, "default build triggered with expected arguments");
+});
+
+test.serial("ui5 build --experimental-css-variables", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ argv["experimental-css-variables"] = true;
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.cssVariables = true;
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs,
+ "Build with activated CSS Variables is called with expected arguments");
+});
+
+test.serial("ui5 build --output-style", async (t) => {
+ const {build, argv, builder, expectedBuilderArgs} = t.context;
+
+ argv["output-style"] = "Flat";
+
+ await build.handler(argv);
+
+ expectedBuilderArgs.outputStyle = "Flat";
+ t.deepEqual(builder.getCall(0).args[0], expectedBuilderArgs,
+ "Build with activated outputStyle='Flat' is called with expected arguments");
+});
diff --git a/packages/cli/test/lib/cli/commands/config.js b/packages/cli/test/lib/cli/commands/config.js
new file mode 100644
index 00000000000..73616ba81fe
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/config.js
@@ -0,0 +1,267 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import chalk from "chalk";
+import path from "node:path";
+import {execa} from "execa";
+import stripAnsi from "strip-ansi";
+import {platform} from "node:process";
+
+const __dirname = import.meta.dirname;
+const ui5Cli = path.join(__dirname, "..", "..", "..", "..", "bin", "ui5.cjs");
+// On Windows, execa@>=9 returns quotes around the path, so it is necessary to add them here
+const ui5CliPath = platform === "win32" ? `"${ui5Cli}"` : ui5Cli;
+const ui5 = (args, options = {}) => execa(ui5Cli, args, options);
+
+function getDefaultArgv() {
+ // This has been taken from the actual argv object yargs provides
+ return {
+ "_": ["build"],
+ "loglevel": "info",
+ "log-level": "info",
+ "logLevel": "info",
+ "perf": false,
+ "silent": false,
+ "include-all-dependencies": false,
+ "all": false,
+ "a": false,
+ "includeAllDependencies": false,
+ "create-build-manifest": false,
+ "createBuildManifest": false,
+ "dest": "./dist",
+ "clean-dest": false,
+ "cleanDest": false,
+ "experimental-css-variables": false,
+ "experimentalCssVariables": false,
+ "$0": "ui5"
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.argv = getDefaultArgv();
+
+ t.context.builder = sinon.stub().resolves();
+ t.context.stdoutWriteStub = sinon.stub(process.stdout, "write");
+ t.context.stderrWriteStub = sinon.stub(process.stderr, "write");
+ t.context.configToJson = sinon.stub().returns({});
+
+ const {default: Configuration} = await import( "@ui5/project/config/Configuration");
+ t.context.Configuration = Configuration;
+ sinon.stub(Configuration, "fromFile").resolves(new Configuration({}));
+ sinon.stub(Configuration, "toFile").resolves();
+
+ t.context.config = await esmock.p("../../../../lib/cli/commands/config.js", {
+ "@ui5/project/config/Configuration": t.context.Configuration
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.config);
+});
+
+test.serial("ui5 config list", async (t) => {
+ const {config, argv, stdoutWriteStub, stderrWriteStub, Configuration} = t.context;
+
+ const configurationStub = new Configuration({});
+ sinon.stub(configurationStub, "toJson").returns({
+ mavenSnapshotEndpointUrl: "my/url",
+ otherConfig: false,
+ pony: 130,
+ horses: null,
+ cows: undefined // Won't be rendered
+ });
+ Configuration.fromFile.resolves(configurationStub);
+
+ argv["_"] = ["list"];
+ await config.handler(argv);
+
+ t.is(stdoutWriteStub.firstCall.firstArg, ` mavenSnapshotEndpointUrl = my/url
+ otherConfig = false
+ pony = 130
+ horses = null
+`, "Logged expected text to stdout");
+ t.is(stderrWriteStub.callCount, 0, "Nothing written to stderr");
+});
+
+test.serial("ui5 config list: No config", async (t) => {
+ const {config, argv, stdoutWriteStub, stderrWriteStub} = t.context;
+
+ argv["_"] = ["list"];
+ await config.handler(argv);
+
+ t.is(stdoutWriteStub.firstCall.firstArg, "",
+ "Logged no text to stdout");
+ t.is(stderrWriteStub.callCount, 0, "Nothing written to stderr");
+});
+
+test.serial("ui5 config get", async (t) => {
+ const {config, argv, stdoutWriteStub, stderrWriteStub, Configuration} = t.context;
+
+ Configuration.fromFile.resolves(new Configuration({
+ mavenSnapshotEndpointUrl: "my/url"
+ }));
+
+ argv["_"] = ["get"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+ await config.handler(argv);
+
+ t.is(stdoutWriteStub.firstCall.firstArg, "my/url\n",
+ "Logged configuration value to stdout");
+ t.is(stderrWriteStub.callCount, 0, "Nothing written to stderr");
+});
+
+test.serial("ui5 config get: Empty value", async (t) => {
+ const {config, argv, stdoutWriteStub} = t.context;
+
+ argv["_"] = ["get"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+ await config.handler(argv);
+
+ t.is(stdoutWriteStub.firstCall.firstArg, "\n", "Logged no value to console");
+});
+
+test.serial("ui5 config set", async (t) => {
+ const {config, argv, stderrWriteStub, stdoutWriteStub, Configuration} = t.context;
+
+ const configurationStub = new Configuration({});
+ sinon.stub(configurationStub, "toJson").returns({
+ mavenSnapshotEndpointUrl: "my/url"
+ });
+
+ Configuration.fromFile.resolves(configurationStub);
+
+ argv["_"] = ["set"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+ argv["value"] = "https://_snapshot_endpoint_";
+ await config.handler(argv);
+
+ t.is(stderrWriteStub.firstCall.firstArg,
+ `Configuration option ${chalk.bold("mavenSnapshotEndpointUrl")} has been updated:
+ mavenSnapshotEndpointUrl = https://_snapshot_endpoint_\n`,
+ "Logged expected message to stderr");
+ t.is(stdoutWriteStub.callCount, 0, "Nothing written to stdout");
+
+ t.is(Configuration.toFile.callCount, 1, "Configuration#toFile got called once");
+ t.is(Configuration.toFile.firstCall.firstArg.toJson().mavenSnapshotEndpointUrl,
+ "https://_snapshot_endpoint_", "Configuration#toFile got called with expected argument");
+});
+
+test.serial("ui5 config set without a value should delete the configuration", async (t) => {
+ const {config, argv, stderrWriteStub, stdoutWriteStub, Configuration} = t.context;
+
+ argv["_"] = ["set"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+ argv["value"] = undefined; // Simulating no value parameter provided to Yargs
+ await config.handler(argv);
+
+ t.is(stderrWriteStub.firstCall.firstArg,
+ `Configuration option ${chalk.bold("mavenSnapshotEndpointUrl")} has been unset\n`,
+ "Logged expected message to stderr");
+ t.is(stdoutWriteStub.callCount, 0, "Nothing written to stdout");
+
+ t.is(Configuration.toFile.callCount, 1, "Configuration#toFile got called once");
+ t.is(Configuration.toFile.firstCall.firstArg.toJson().mavenSnapshotEndpointUrl,
+ undefined, "Configuration#toFile got called with expected argument");
+});
+
+test.serial("ui5 config set with an empty value should delete the configuration", async (t) => {
+ const {config, argv, stderrWriteStub, stdoutWriteStub, Configuration} = t.context;
+
+ argv["_"] = ["set"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+ argv["value"] = ""; // Simulating empty value provided to Yargs using quotes ""
+ await config.handler(argv);
+
+ t.is(stderrWriteStub.firstCall.firstArg,
+ `Configuration option ${chalk.bold("mavenSnapshotEndpointUrl")} has been unset\n`,
+ "Logged expected message to stderr");
+ t.is(stdoutWriteStub.callCount, 0, "Nothing written to stdout");
+
+ t.is(Configuration.toFile.callCount, 1, "Configuration#toFile got called once");
+ t.is(Configuration.toFile.firstCall.firstArg.toJson().mavenSnapshotEndpointUrl,
+ undefined, "Configuration#toFile got called with expected argument");
+});
+
+test.serial("ui5 config set null should update the configuration", async (t) => {
+ const {config, argv, stderrWriteStub, stdoutWriteStub, Configuration} = t.context;
+
+ argv["_"] = ["set"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+
+ // Yargs would never provide us with other types than string. Still, our code should
+ // check for empty strings and nothing else (like falsy)
+ argv["value"] = 0;
+ await config.handler(argv);
+
+ t.is(stderrWriteStub.firstCall.firstArg,
+ `Configuration option ${chalk.bold("mavenSnapshotEndpointUrl")} has been updated:
+ mavenSnapshotEndpointUrl = 0\n`,
+ "Logged expected message to stderr");
+ t.is(stdoutWriteStub.callCount, 0, "Nothing written to stdout");
+
+ t.is(Configuration.toFile.callCount, 1, "Configuration#toFile got called once");
+ t.is(Configuration.toFile.firstCall.firstArg.toJson().mavenSnapshotEndpointUrl,
+ 0, "Configuration#toFile got called with expected argument");
+});
+
+test.serial("ui5 config set false should update the configuration", async (t) => {
+ const {config, argv, stderrWriteStub, stdoutWriteStub, Configuration} = t.context;
+
+ argv["_"] = ["set"];
+ argv["option"] = "mavenSnapshotEndpointUrl";
+
+ // Yargs would never provide us with other types than string. Still, our code should
+ // check for empty strings and nothing else (like falsyness)
+ argv["value"] = false;
+ await config.handler(argv);
+
+ t.is(stderrWriteStub.firstCall.firstArg,
+ `Configuration option ${chalk.bold("mavenSnapshotEndpointUrl")} has been updated:
+ mavenSnapshotEndpointUrl = false\n`,
+ "Logged expected message to stderr");
+ t.is(stdoutWriteStub.callCount, 0, "Nothing written to stdout");
+
+ t.is(Configuration.toFile.callCount, 1, "Configuration#toFile got called once");
+ t.is(Configuration.toFile.firstCall.firstArg.toJson().mavenSnapshotEndpointUrl,
+ false, "Configuration#toFile got called with expected argument");
+});
+
+test.serial("ui5 config invalid option", async (t) => {
+ await t.throwsAsync(ui5(["config", "set", "_invalid_key_", "https://_snapshot_endpoint_"]), {
+ message: ($) => {
+ // stderr might include debug information
+ return $.includes("Command failed with exit code 1") &&
+ $.includes("Invalid values") &&
+ $.includes(`Given: "_invalid_key_", Choices: "`);
+ }
+ });
+});
+
+test.serial("ui5 config empty option", async (t) => {
+ await t.throwsAsync(ui5(["config", "set"]), {
+ message: ($) => {
+ const message = stripAnsi($);
+ // stderr might include debug information
+
+ return message.includes(`Command failed with exit code 1: ${ui5CliPath} config set`) &&
+ message.includes(`Command Failed:
+Not enough non-option arguments: got 0, need at least 1
+
+See 'ui5 --help'`);
+ }
+ });
+});
+
+test.serial("ui5 config unknown command", async (t) => {
+ await t.throwsAsync(ui5(["config", "foo"]), {
+ message: ($) => {
+ const message = stripAnsi($);
+ return message.includes(`Command failed with exit code 1: ${ui5CliPath} config foo`) &&
+ message.includes(`Command Failed:
+Unknown argument: foo
+
+See 'ui5 --help'`);
+ }
+ });
+});
diff --git a/packages/cli/test/lib/cli/commands/init.js b/packages/cli/test/lib/cli/commands/init.js
new file mode 100644
index 00000000000..33785f14367
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/init.js
@@ -0,0 +1,54 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.initCommand);
+});
+
+test.serial("Writes ui5.yaml to fs", async (t) => {
+ const ui5YamlPath = "./ui5.yaml";
+ const ui5Yaml = `
+ specVersion: "0.1"
+ metadata:
+ name: sample-app
+ type: application`;
+
+ const fsWriteFileStub = sinon.stub().resolves();
+ const jsyamlDumpStub = sinon.stub().returns(ui5Yaml);
+
+ const initCommand = t.context.initCommand = await esmock.p("../../../../lib/cli/commands/init.js", {
+ "../../../../lib/utils/fsHelper": {
+ exists: sinon.stub().resolves(false)
+ },
+ "../../../../lib/init/init": sinon.stub().resolves({}),
+ "js-yaml": {
+ dump: jsyamlDumpStub
+ },
+ "node:path": {
+ resolve: () => ui5YamlPath
+ },
+ "node:fs/promises": {
+ writeFile: fsWriteFileStub
+ }
+ });
+
+ await initCommand.handler({});
+
+ t.is(fsWriteFileStub.getCall(0).args[0], ui5YamlPath, "Passes yaml path to write the yaml file to");
+ t.is(fsWriteFileStub.getCall(0).args[1], ui5Yaml, "Passes yaml content to write to fs");
+ t.deepEqual(jsyamlDumpStub.getCall(0).args[1], {quotingType: `"`}, "Enforce usage of double quotes in yaml files");
+});
+
+test.serial("Error: throws if ui5.yaml already exists", async (t) => {
+ const initCommand = t.context.initCommand = await esmock.p("../../../../lib/cli/commands/init.js", {
+ "../../../../lib/utils/fsHelper": {
+ exists: sinon.stub().resolves(true)
+ }
+ });
+
+ await t.throwsAsync(initCommand.handler(), {
+ message: "Initialization not possible: ui5.yaml already exists"
+ });
+});
diff --git a/packages/cli/test/lib/cli/commands/remove.js b/packages/cli/test/lib/cli/commands/remove.js
new file mode 100644
index 00000000000..a2b0afbb56f
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/remove.js
@@ -0,0 +1,134 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+async function createMock(t, yamlUpdated = true) {
+ t.context.frameworkRemoveStub = sinon.stub().resolves({yamlUpdated});
+ t.context.removeCommand = await esmock.p("../../../../lib/cli/commands/remove.js", {
+ "../../../../lib/framework/remove.js": t.context.frameworkRemoveStub
+ });
+}
+
+async function assertRemoveHandler(t, {argv, expectedLibraries, expectedConsoleLog}) {
+ await createMock(t);
+ await t.context.removeCommand.handler(argv);
+
+ t.is(t.context.frameworkRemoveStub.callCount, 1, "Remove function should be called once");
+ t.deepEqual(t.context.frameworkRemoveStub.getCall(0).args, [
+ {
+ libraries: expectedLibraries,
+ projectGraphOptions: {
+ dependencyDefinition: undefined,
+ config: undefined
+ }
+ }],
+ "Remove function should be called with expected args");
+
+ t.is(t.context.processStdoutStub.callCount, expectedConsoleLog.length,
+ "console.log should be called " + expectedConsoleLog.length + " times");
+ expectedConsoleLog.forEach((expectedLog, i) => {
+ t.deepEqual(t.context.processStdoutStub.getCall(i).args, [expectedLog],
+ "console.log should be called with expected string on call index " + i);
+ });
+}
+
+async function assertFailingRemoveHandler(t, {argv, expectedMessage}) {
+ await createMock(t);
+ const exception = await t.throwsAsync(t.context.removeCommand.handler(argv));
+
+ t.is(exception.message, expectedMessage, "Remove handler should throw expected error");
+ t.is(t.context.frameworkRemoveStub.callCount, 0, "Remove function should not be called");
+}
+
+async function assertFailingYamlUpdateRemoveHandler(t, {argv, expectedMessage}) {
+ await createMock(t, false);
+
+ const exception = await t.throwsAsync(t.context.removeCommand.handler(argv));
+
+ t.is(exception.message, expectedMessage, "Remove handler should throw expected error");
+ t.is(t.context.frameworkRemoveStub.callCount, 1, "Remove function should be called once");
+}
+
+test.beforeEach((t) => {
+ t.context.processStdoutStub = sinon.stub(process.stdout, "write");
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.removeCommand);
+});
+
+test.serial("Accepts single library", async (t) => {
+ await assertRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1"]},
+ expectedLibraries: [{name: "sap.ui.lib1"}],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Removed framework library sap.ui.lib1 as dependency",
+ "\n"
+ ]
+ });
+});
+
+test.serial("Accepts multiple libraries", async (t) => {
+ await assertRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib2"]},
+ expectedLibraries: [{name: "sap.ui.lib1"}, {name: "sap.ui.lib2"}],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Removed framework libraries sap.ui.lib1 sap.ui.lib2 as dependencies",
+ "\n"
+ ]
+ });
+});
+
+test.serial("Accepts multiple libraries duplicates", async (t) => {
+ await assertRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib1", "sap.ui.lib2"]},
+ expectedLibraries: [{name: "sap.ui.lib1"}, {name: "sap.ui.lib2"}],
+ expectedConsoleLog: [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "Removed framework libraries sap.ui.lib1 sap.ui.lib2 as dependencies",
+ "\n"
+ ]
+ });
+});
+
+test.serial("Rejects on empty framework-libraries", async (t) => {
+ await assertFailingRemoveHandler(t, {
+ argv: {"framework-libraries": ""},
+ expectedMessage: "Missing mandatory parameter framework-libraries"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (single library)", async (t) => {
+ await assertFailingYamlUpdateRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1"]},
+ expectedMessage: "Internal error while removing framework library sap.ui.lib1 to ui5.yaml"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (multiple libraries)", async (t) => {
+ await assertFailingYamlUpdateRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib2"]},
+ expectedMessage: "Internal error while removing framework libraries sap.ui.lib1 sap.ui.lib2 to ui5.yaml"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (single library; with config path)", async (t) => {
+ await assertFailingYamlUpdateRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1"], "config": "/path/to/ui5.yaml"},
+ expectedMessage: "Internal error while removing framework library sap.ui.lib1 to config at /path/to/ui5.yaml"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (multiple libraries; with config path)", async (t) => {
+ await assertFailingYamlUpdateRemoveHandler(t, {
+ argv: {"framework-libraries": ["sap.ui.lib1", "sap.ui.lib2"], "config": "/path/to/ui5.yaml"},
+ expectedMessage:
+ "Internal error while removing framework libraries sap.ui.lib1 sap.ui.lib2 to config at /path/to/ui5.yaml"
+ });
+});
diff --git a/packages/cli/test/lib/cli/commands/serve.js b/packages/cli/test/lib/cli/commands/serve.js
new file mode 100644
index 00000000000..1f20ba09c48
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/serve.js
@@ -0,0 +1,853 @@
+import path from "node:path";
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import chalk from "chalk";
+
+function getDefaultArgv() {
+ // This has been taken from the actual argv object yargs provides
+ return {
+ "_": ["serve"],
+ "loglevel": "info",
+ "log-level": "info",
+ "logLevel": "info",
+ "perf": false,
+ "silent": false,
+ "h2": false,
+ "simple-index": false,
+ "simpleIndex": false,
+ "accept-remote-connections": false,
+ "acceptRemoteConnections": false,
+ "key": "/home/.ui5/server/server.key",
+ "cert": "/home/.ui5/server/server.crt",
+ "sap-csp-policies": false,
+ "sapCspPolicies": false,
+ "serve-csp-reports": false,
+ "serveCspReports": false,
+ "cache-mode": "Default",
+ "cacheMode": "Default",
+ "$0": "ui5"
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.argv = getDefaultArgv();
+
+ t.context.server = {
+ serve: sinon.stub().returns({
+ h2: false,
+ port: 8080
+ })
+ };
+ t.context.sslUtil = {
+ getSslCertificate: sinon.stub().resolves()
+ };
+
+ t.context.getServerSettings = sinon.stub().returns({});
+ t.context.fakeGraph = {
+ getRoot: () => {
+ return {
+ getServerSettings: t.context.getServerSettings
+ };
+ }
+ };
+
+ t.context.graph = {
+ graphFromStaticFile: sinon.stub().resolves(t.context.fakeGraph),
+ graphFromPackageDependencies: sinon.stub().resolves(t.context.fakeGraph)
+ };
+
+
+ t.context.consoleOutput = "";
+ t.context.processStderrWrite = sinon.stub(process.stderr, "write").callsFake((message) => {
+ // NOTE: This fake impl only supports one string arg passed to console.log
+ t.context.consoleOutput += message;
+ });
+ t.context.processStdoutWrite = sinon.stub(process.stdout, "write").callsFake((message) => {
+ // NOTE: This fake impl only supports one string arg passed to console.log
+ t.context.consoleOutput += message;
+ });
+
+ t.context.open = sinon.stub();
+
+ t.context.serve = await esmock.p("../../../../lib/cli/commands/serve.js", {
+ "@ui5/server": t.context.server,
+ "@ui5/server/internal/sslUtil": t.context.sslUtil,
+ "@ui5/project/graph": t.context.graph,
+ "open": t.context.open
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.serve);
+});
+
+test.serial("ui5 serve: default", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --h2", async (t) => {
+ const {argv, serve, graph, server, fakeGraph, sslUtil} = t.context;
+
+ sslUtil.getSslCertificate.resolves({
+ key: "random-key",
+ cert: "random-cert"
+ });
+
+ server.serve.returns({
+ h2: true,
+ port: 8443
+ });
+
+ argv.h2 = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: https://localhost:8443
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ changePortIfInUse: true,
+ h2: true,
+ key: "random-key",
+ cert: "random-cert",
+ port: 8443,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+
+ t.is(sslUtil.getSslCertificate.callCount, 1);
+ t.deepEqual(sslUtil.getSslCertificate.getCall(0).args, [
+ "/home/.ui5/server/server.key",
+ "/home/.ui5/server/server.crt"
+ ]);
+});
+
+test.serial("ui5 serve --accept-remote-connections", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.acceptRemoteConnections = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `
+${chalk.bold("⚠️ This server is accepting connections from all hosts on your network")}
+${chalk.dim.underline("Please Note:")}
+${chalk.bold.dim("* This server is intended for development purposes only. Do not use it in production.")}
+${chalk.dim("* Vulnerable (custom-)middleware can pose a threat to your system when exposed to the network")}
+${chalk.dim("* The use of proxy-middleware with preconfigured credentials might enable unauthorized access " +
+ "to a target system for third parties on your network")}
+
+Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: true,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --open", async (t) => {
+ const {argv, serve, graph, server, fakeGraph, open} = t.context;
+
+ argv.open = "index.html";
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+
+ t.is(open.callCount, 1);
+ t.deepEqual(open.getCall(0).args, [
+ "http://localhost:8080/index.html"
+ ]);
+});
+
+test.serial("ui5 serve --open (opens default url)", async (t) => {
+ const {argv, serve, graph, server, fakeGraph, open} = t.context;
+
+ argv.open = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+
+ t.is(open.callCount, 1);
+ t.deepEqual(open.getCall(0).args, [
+ "http://localhost:8080"
+ ]);
+});
+
+test.serial("ui5 serve --config", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "ui5.yaml");
+ argv.config = fakePath;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: fakePath, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --dependency-definition", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "dependencies.yaml");
+ argv.dependencyDefinition = fakePath;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromPackageDependencies.callCount, 0);
+ t.is(graph.graphFromStaticFile.callCount, 1);
+ t.deepEqual(graph.graphFromStaticFile.getCall(0).args, [{
+ filePath: fakePath, versionOverride: undefined,
+ cacheMode: "Default", rootConfigPath: undefined
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false
+ }
+ ]);
+});
+
+test.serial("ui5 serve --dependency-definition / --config", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ const fakeDependenciesPath = path.join("/", "path", "to", "dependencies.yaml");
+ argv.dependencyDefinition = fakeDependenciesPath;
+
+ const fakeConfigPath = path.join("/", "path", "to", "ui5.yaml");
+ argv.config = fakeConfigPath;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromPackageDependencies.callCount, 0);
+ t.is(graph.graphFromStaticFile.callCount, 1);
+ t.deepEqual(graph.graphFromStaticFile.getCall(0).args, [{
+ filePath: fakeDependenciesPath, versionOverride: undefined,
+ cacheMode: "Default", rootConfigPath: fakeConfigPath
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false
+ }
+ ]);
+});
+
+test.serial("ui5 serve --framework-version", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.frameworkVersion = "1.234.5";
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: "1.234.5",
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --cache-mode", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.cacheMode = "Force";
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Force",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --workspace", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.workspace = "dolphin";
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: "dolphin",
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --no-workspace", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.workspace = false;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: null,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --workspace-config", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "ui5-workspace.yaml");
+ argv.workspaceConfig = fakePath;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: fakePath, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --sap-csp-policies", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.sapCspPolicies = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: true,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --serve-csp-reports", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.serveCspReports = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: true,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --simple-index", async (t) => {
+ const {argv, serve, graph, server, fakeGraph} = t.context;
+
+ argv.simpleIndex = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:8080
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: true,
+ h2: false,
+ key: undefined,
+ port: 8080,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: true,
+ }
+ ]);
+});
+
+test.serial("ui5 serve with ui5.yaml port setting", async (t) => {
+ const {argv, serve, graph, server, fakeGraph, getServerSettings} = t.context;
+
+ getServerSettings.returns({
+ httpPort: 3333
+ });
+
+ server.serve.returns({
+ h2: false,
+ port: 3333
+ });
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: http://localhost:3333
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ cert: undefined,
+ changePortIfInUse: false,
+ h2: false,
+ key: undefined,
+ port: 3333,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+});
+
+test.serial("ui5 serve --h2 with ui5.yaml port setting", async (t) => {
+ const {argv, serve, graph, server, fakeGraph, sslUtil, getServerSettings} = t.context;
+
+ sslUtil.getSslCertificate.resolves({
+ key: "random-key",
+ cert: "random-cert"
+ });
+
+ getServerSettings.returns({
+ httpsPort: 4444
+ });
+
+ server.serve.returns({
+ h2: true,
+ port: 4444
+ });
+
+ argv.h2 = true;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: https://localhost:4444
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ changePortIfInUse: false,
+ h2: true,
+ key: "random-key",
+ cert: "random-cert",
+ port: 4444,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+
+ t.is(sslUtil.getSslCertificate.callCount, 1);
+ t.deepEqual(sslUtil.getSslCertificate.getCall(0).args, [
+ "/home/.ui5/server/server.key",
+ "/home/.ui5/server/server.crt"
+ ]);
+});
+
+test.serial("ui5 serve --h2 with ui5.yaml port setting and port CLI argument", async (t) => {
+ const {argv, serve, graph, server, fakeGraph, sslUtil, getServerSettings} = t.context;
+
+ sslUtil.getSslCertificate.resolves({
+ key: "random-key",
+ cert: "random-cert"
+ });
+
+ getServerSettings.returns({
+ httpsPort: 4444
+ });
+
+ server.serve.returns({
+ h2: true,
+ port: 5555
+ });
+
+ argv.h2 = true;
+ argv.port = 5555;
+
+ await serve.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput, `Server started
+URL: https://localhost:5555
+`);
+
+ t.is(server.serve.callCount, 1);
+ t.deepEqual(server.serve.getCall(0).args, [
+ fakeGraph,
+ {
+ acceptRemoteConnections: false,
+ changePortIfInUse: false,
+ h2: true,
+ key: "random-key",
+ cert: "random-cert",
+ port: 5555,
+ sendSAPTargetCSP: false,
+ serveCSPReports: false,
+ simpleIndex: false,
+ }
+ ]);
+
+ t.is(sslUtil.getSslCertificate.callCount, 1);
+ t.deepEqual(sslUtil.getSslCertificate.getCall(0).args, [
+ "/home/.ui5/server/server.key",
+ "/home/.ui5/server/server.crt"
+ ]);
+});
diff --git a/packages/cli/test/lib/cli/commands/tree.js b/packages/cli/test/lib/cli/commands/tree.js
new file mode 100644
index 00000000000..f8e8fcad689
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/tree.js
@@ -0,0 +1,731 @@
+import path from "node:path";
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import chalk from "chalk";
+
+function getDefaultArgv() {
+ // This has been taken from the actual argv object yargs provides
+ return {
+ "_": ["tree"],
+ "loglevel": "info",
+ "log-level": "info",
+ "logLevel": "info",
+ "perf": false,
+ "silent": false,
+ "cache-mode": "Default",
+ "cacheMode": "Default",
+ "flat": false,
+ "level": undefined,
+ "$0": "ui5"
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.argv = getDefaultArgv();
+
+ t.context.traverseBreadthFirst = sinon.stub();
+ t.context.getExtensionNames = sinon.stub().returns([]);
+ t.context.getExtension = sinon.stub().returns();
+ const fakeGraph = {
+ traverseBreadthFirst: t.context.traverseBreadthFirst,
+ getExtensionNames: t.context.getExtensionNames,
+ getExtension: t.context.getExtension,
+ };
+ t.context.graph = {
+ graphFromStaticFile: sinon.stub().resolves(fakeGraph),
+ graphFromPackageDependencies: sinon.stub().resolves(fakeGraph)
+ };
+
+ t.context.consoleOutput = "";
+ t.context.processStderrWrite = sinon.stub(process.stderr, "write").callsFake((message) => {
+ t.context.consoleOutput += message;
+ });
+ t.context.processStdoutWrite = sinon.stub(process.stdout, "write").callsFake((message) => {
+ t.context.consoleOutput += message;
+ });
+
+ t.context.tree = await esmock.p("../../../../lib/cli/commands/tree.js", {
+ "@ui5/project/graph": t.context.graph
+ });
+});
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.tree);
+});
+
+test.serial("ui5 tree (Without dependencies)", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency1", "dependency2"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency2"),
+ getNamespace: sinon.stub().returns("test/dependency2"),
+ getVersion: sinon.stub().returns("2.0.0"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency2"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency1"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency1"),
+ getNamespace: sinon.stub().returns(null),
+ getVersion: sinon.stub().returns("1.1.1"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency3"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency3"),
+ getNamespace: sinon.stub().returns(null),
+ getVersion: sinon.stub().returns("3.3.3"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency3"),
+ isFrameworkProject: sinon.stub().returns(true),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (4):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+ ├─ ${chalk.bold("dependency1")} ${chalk.dim("(1.1.1, library) ")}\
+${chalk.dim.italic("/home/dependency1")}
+ │ ╰─ ${chalk.blue.bold("dependency3")} ${chalk.dim("(3.3.3, library) ")}\
+${chalk.dim.italic("/home/dependency3")}
+ ╰─ ${chalk.bold("dependency2")} ${chalk.inverse("test/dependency2")} \
+${chalk.dim("(2.0.0, library) ")}${chalk.dim.italic("/home/dependency2")}
+ ╰─ ${chalk.bold("dependency1")} ${chalk.dim("(1.1.1, library) ")}${chalk.dim.italic("/home/dependency1")}
+ ╰─ ${chalk.blue.bold("dependency3")} ${chalk.dim("(3.3.3, library) ")}\
+${chalk.dim.italic("/home/dependency3")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --flat", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency1", "dependency2"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency2"),
+ getNamespace: sinon.stub().returns("test/dependency2"),
+ getVersion: sinon.stub().returns("2.0.0"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency2"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency1"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency1"),
+ getNamespace: sinon.stub().returns(null),
+ getVersion: sinon.stub().returns("1.1.1"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency3"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency3"),
+ getNamespace: sinon.stub().returns(null),
+ getVersion: sinon.stub().returns("3.3.3"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency3"),
+ isFrameworkProject: sinon.stub().returns(true),
+ },
+ dependencies: []
+ });
+ });
+
+ argv.flat = true;
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (4):")}
+├─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+├─ ${chalk.bold("dependency2")} ${chalk.inverse("test/dependency2")} \
+${chalk.dim("(2.0.0, library) ")}${chalk.dim.italic("/home/dependency2")}
+├─ ${chalk.bold("dependency1")} ${chalk.dim("(1.1.1, library) ")}\
+${chalk.dim.italic("/home/dependency1")}
+╰─ ${chalk.blue.bold("dependency3")} ${chalk.dim("(3.3.3, library) ")}\
+${chalk.dim.italic("/home/dependency3")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --level 1", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency1", "dependency2"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency2"),
+ getNamespace: sinon.stub().returns("test/dependency2"),
+ getVersion: sinon.stub().returns("2.0.0"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency2"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency1"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency1"),
+ getNamespace: sinon.stub().returns(null),
+ getVersion: sinon.stub().returns("1.1.1"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: ["dependency3"]
+ });
+ await fn({
+ project: {
+ getName: sinon.stub().returns("dependency3"),
+ getNamespace: sinon.stub().returns(null),
+ getVersion: sinon.stub().returns("3.3.3"),
+ getType: sinon.stub().returns("library"),
+ getRootPath: sinon.stub().returns("/home/dependency3"),
+ isFrameworkProject: sinon.stub().returns(true),
+ },
+ dependencies: []
+ });
+ });
+
+ argv.level = 1;
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (4):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+ ├─ ${chalk.bold("dependency1")} ${chalk.dim("(1.1.1, library) ")}\
+${chalk.dim.italic("/home/dependency1")}
+ │ ╰─ ${chalk.dim.italic("Dependencies below Level 1 are hidden")}
+ ╰─ ${chalk.bold("dependency2")} ${chalk.inverse("test/dependency2")} \
+${chalk.dim("(2.0.0, library) ")}${chalk.dim.italic("/home/dependency2")}
+ ╰─ ${chalk.dim.italic("Dependencies below Level 1 are hidden")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --level 'string' throws", async (t) => {
+ const {argv, tree, traverseBreadthFirst,} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ argv.level = NaN; // Yargs already takes care of transforming non-numeric values to NaN
+
+ await t.throwsAsync(tree.handler(argv), {
+ message: `The provided 'level' option is not a number`
+ });
+});
+
+test.serial("ui5 tree (With extensions)", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph, getExtension, getExtensionNames} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+ getExtensionNames.returns(["extension1", "extension2"]);
+
+ getExtension.onFirstCall().returns({
+ getName: sinon.stub().returns("extension1"),
+ getVersion: sinon.stub().returns("3.0.0"),
+ getType: sinon.stub().returns("task"),
+ getRootPath: sinon.stub().returns("/home/extension1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ }).onSecondCall().returns({
+ getName: sinon.stub().returns("extension2"),
+ getVersion: sinon.stub().returns("5.0.0"),
+ getType: sinon.stub().returns("middleware"),
+ getRootPath: sinon.stub().returns("/home/extension2"),
+ isFrameworkProject: sinon.stub().returns(false),
+ });
+
+ await tree.handler(argv);
+
+ t.is(getExtensionNames.callCount, 1,
+ "getExtensionNames got called once");
+ t.is(getExtension.callCount, 2,
+ "getExtension got called once");
+ t.is(getExtension.getCall(0).args[0], "extension1",
+ "getExtension called with expected extension name");
+ t.is(getExtension.getCall(1).args[0], "extension2",
+ "getExtension called with expected extension name");
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (2):")}
+├─ extension1 ${chalk.dim("(3.0.0, task) ")}\
+${chalk.dim.italic("/home/extension1")}
+╰─ extension2 ${chalk.dim("(5.0.0, middleware) ")}\
+${chalk.dim.italic("/home/extension2")}
+`);
+});
+
+test.serial("ui5 tree --perf", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ argv.perf = true;
+
+ sinon.stub(process, "hrtime")
+ .withArgs().returns([0, 0])
+ .withArgs([0, 0]).returns([0, 1000000]);
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+
+${chalk.blue(`Dependency graph generation took ${chalk.bold("1 ms")}`)}
+`);
+});
+
+test.serial("ui5 tree --framework-version", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ argv.frameworkVersion = "1.234.5";
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: "1.234.5",
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --cache-mode", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ argv.cacheMode = "Force";
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false)
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Force",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --config", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "ui5.yaml");
+ argv.config = fakePath;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: fakePath, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --workspace", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ argv.workspace = "dolphin";
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: "dolphin",
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --no-workspace", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ argv.workspace = false;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: undefined, workspaceName: null,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --workspace-config", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "ui5-workspace.yaml");
+ argv.workspaceConfig = fakePath;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromStaticFile.callCount, 0);
+ t.is(graph.graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graph.graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: undefined, versionOverride: undefined,
+ workspaceConfigPath: fakePath, workspaceName: undefined,
+ cacheMode: "Default",
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
+
+test.serial("ui5 tree --dependency-definition", async (t) => {
+ const {argv, tree, traverseBreadthFirst, graph} = t.context;
+
+ const fakePath = path.join("/", "path", "to", "dependencies.yaml");
+ argv.dependencyDefinition = fakePath;
+
+ traverseBreadthFirst.callsFake(async (fn) => {
+ await fn({
+ project: {
+ getName: sinon.stub().returns("project1"),
+ getNamespace: sinon.stub().returns("test/project1"),
+ getVersion: sinon.stub().returns("1.0.0"),
+ getType: sinon.stub().returns("application"),
+ getRootPath: sinon.stub().returns("/home/project1"),
+ isFrameworkProject: sinon.stub().returns(false),
+ },
+ dependencies: []
+ });
+ });
+
+ await tree.handler(argv);
+
+ t.is(graph.graphFromPackageDependencies.callCount, 0);
+ t.is(graph.graphFromStaticFile.callCount, 1);
+ t.deepEqual(graph.graphFromStaticFile.getCall(0).args, [{
+ filePath: fakePath, versionOverride: undefined, cacheMode: "Default"
+ }]);
+
+ t.is(t.context.consoleOutput,
+ `${chalk.bold.underline("Dependencies (1):")}
+╰─ ${chalk.bold("project1")} ${chalk.inverse("test/project1")} ${chalk.dim("(1.0.0, application) ")}\
+${chalk.dim.italic("/home/project1")}
+
+${chalk.bold.underline("Extensions (0):")}
+${chalk.italic("None")}
+`);
+});
diff --git a/packages/cli/test/lib/cli/commands/use.js b/packages/cli/test/lib/cli/commands/use.js
new file mode 100644
index 00000000000..061ec786d88
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/use.js
@@ -0,0 +1,311 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+async function assertUseHandler(t, {argv, expectedFrameworkOptions}) {
+ const {useCommand, frameworkUseStub} = t.context;
+
+ frameworkUseStub.resolves({
+ usedFramework: undefined, // not required for this test
+ usedVersion: undefined, // not required for this test
+ yamlUpdated: true
+ });
+
+ await useCommand.handler(argv);
+
+ t.is(frameworkUseStub.callCount, 1, "Use function should be called once");
+ t.deepEqual(frameworkUseStub.getCall(0).args, [
+ {
+ frameworkOptions: expectedFrameworkOptions,
+ projectGraphOptions: {
+ dependencyDefinition: undefined,
+ config: undefined
+ }
+ }],
+ "Use function should be called with expected args");
+}
+
+async function assertFailingUseHandler(t, {argv, expectedMessage}) {
+ const {useCommand, frameworkUseStub} = t.context;
+
+ frameworkUseStub.resolves({
+ usedFramework: undefined, // not required for this test
+ usedVersion: undefined // not required for this test
+ });
+
+ const exception = await t.throwsAsync(useCommand.handler(argv));
+
+ t.is(exception.message, expectedMessage, "Use handler should throw expected error");
+ t.is(frameworkUseStub.callCount, 0, "Use function should not be called");
+}
+
+async function assertFailingYamlUpdateUseHandler(t, {argv, expectedMessage}) {
+ const {useCommand, frameworkUseStub} = t.context;
+
+ frameworkUseStub.resolves({
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: false
+ });
+
+ const exception = await t.throwsAsync(useCommand.handler(argv));
+
+ t.is(exception.message, expectedMessage, "Use handler should throw expected error");
+ t.is(frameworkUseStub.callCount, 1, "Use function should be called once");
+}
+
+test.beforeEach(async (t) => {
+ t.context.processStdoutStub = sinon.stub(process.stdout, "write");
+
+ t.context.frameworkUseStub = sinon.stub();
+
+ t.context.useCommand = await esmock.p("../../../../lib/cli/commands/use.js", {
+ "../../../../lib/framework/use": t.context.frameworkUseStub
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.useCommand);
+});
+
+test.serial("Accepts framework name and version (SAPUI5@1.76.0)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@1.76.0"},
+ expectedFrameworkOptions: {
+ name: "SAPUI5",
+ version: "1.76.0"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (OpenUI5@1.76.0)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "OpenUI5@1.76.0"},
+ expectedFrameworkOptions: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (SAPUI5@1.76)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@1.76"},
+ expectedFrameworkOptions: {
+ name: "SAPUI5",
+ version: "1.76"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (OpenUI5@1.76)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "OpenUI5@1.76"},
+ expectedFrameworkOptions: {
+ name: "OpenUI5",
+ version: "1.76"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (SAPUI5@1.79.0-SNAPSHOT)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@1.79.0-SNAPSHOT"},
+ expectedFrameworkOptions: {
+ name: "SAPUI5",
+ version: "1.79.0-SNAPSHOT"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (OpenUI5@1.79.0-SNAPSHOT)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "OpenUI5@1.79.0-SNAPSHOT"},
+ expectedFrameworkOptions: {
+ name: "OpenUI5",
+ version: "1.79.0-SNAPSHOT"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (SAPUI5@latest)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@latest"},
+ expectedFrameworkOptions: {
+ name: "SAPUI5",
+ version: "latest"
+ }
+ });
+});
+
+test.serial("Accepts framework name and version (OpenUI5@latest)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "OpenUI5@latest"},
+ expectedFrameworkOptions: {
+ name: "OpenUI5",
+ version: "latest"
+ }
+ });
+});
+
+test.serial("Accepts framework name and uses latest (SAPUI5)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "SAPUI5"},
+ expectedFrameworkOptions: {
+ name: "SAPUI5",
+ version: "latest"
+ }
+ });
+});
+
+test.serial("Accepts framework name and uses latest (sapui5)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "sapui5"},
+ expectedFrameworkOptions: {
+ name: "sapui5",
+ version: "latest"
+ }
+ });
+});
+
+test.serial("Accepts framework name and uses latest (OpenUI5)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "OpenUI5"},
+ expectedFrameworkOptions: {
+ name: "OpenUI5",
+ version: "latest"
+ }
+ });
+});
+
+test.serial("Accepts framework version (1.76.0)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "1.76.0"},
+ expectedFrameworkOptions: {
+ name: null,
+ version: "1.76.0"
+ }
+ });
+});
+
+test.serial("Accepts framework version (1.76)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "1.76"},
+ expectedFrameworkOptions: {
+ name: null,
+ version: "1.76"
+ }
+ });
+});
+
+test.serial("Accepts framework version (latest)", async (t) => {
+ await assertUseHandler(t, {
+ argv: {"framework-info": "latest"},
+ expectedFrameworkOptions: {
+ name: null,
+ version: "latest"
+ }
+ });
+});
+
+test.serial("Rejects on empty framework-info", async (t) => {
+ await assertFailingUseHandler(t, {
+ argv: {"framework-info": ""},
+ expectedMessage: "Invalid framework info: "
+ });
+});
+
+test.serial("Rejects on invalid framework-info (@1.2.3)", async (t) => {
+ await assertFailingUseHandler(t, {
+ argv: {"framework-info": "@1.2.3"},
+ expectedMessage: "Invalid framework info: @1.2.3"
+ });
+});
+
+test.serial("Rejects on invalid framework-info (SAPUI5@)", async (t) => {
+ await assertFailingUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@"},
+ expectedMessage: "Invalid framework info: SAPUI5@"
+ });
+});
+
+test.serial("Rejects on invalid framework-info (@SAPUI5@)", async (t) => {
+ await assertFailingUseHandler(t, {
+ argv: {"framework-info": "@SAPUI5@"},
+ expectedMessage: "Invalid framework info: @SAPUI5@"
+ });
+});
+
+test.serial("Rejects on invalid framework-info (SAPUI5@1.2.3@4.5.6)", async (t) => {
+ await assertFailingUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@1.2.3@4.5.6"},
+ expectedMessage: "Invalid framework info: SAPUI5@1.2.3@4.5.6"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated", async (t) => {
+ await assertFailingYamlUpdateUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@1.76.0"},
+ expectedMessage: "Internal error while updating ui5.yaml to SAPUI5 version 1.76.0"
+ });
+});
+
+test.serial("Rejects when YAML could not be updated (with config path)", async (t) => {
+ await assertFailingYamlUpdateUseHandler(t, {
+ argv: {"framework-info": "SAPUI5@1.76.0", "config": "/path/to/ui5.yaml"},
+ expectedMessage: "Internal error while updating config at /path/to/ui5.yaml to SAPUI5 version 1.76.0"
+ });
+});
+
+test.serial("Logs framework name, version and default config path when updating config", async (t) => {
+ const {useCommand, frameworkUseStub} = t.context;
+
+ frameworkUseStub.resolves({
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ });
+
+ await useCommand.handler({"framework-info": "SAPUI5@1.76.0"});
+
+ const expectedConsoleLog = [
+ "Updated configuration written to ui5.yaml",
+ "\n",
+ "This project is now using SAPUI5 version 1.76.0",
+ "\n"
+ ];
+
+ t.is(t.context.processStdoutStub.callCount, expectedConsoleLog.length,
+ "console.log should be called " + expectedConsoleLog.length + " times");
+ expectedConsoleLog.forEach((expectedLog, i) => {
+ t.deepEqual(t.context.processStdoutStub.getCall(i).args, [expectedLog],
+ "console.log should be called with expected string on call index " + i);
+ });
+});
+
+test.serial("Logs framework name, version and custom config path when updating config", async (t) => {
+ const {useCommand, frameworkUseStub} = t.context;
+
+ frameworkUseStub.resolves({
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ });
+
+ await useCommand.handler({"framework-info": "SAPUI5@1.76.0", "config": "/path/to/ui5.yaml"});
+
+ const expectedConsoleLog = [
+ "Updated configuration written to /path/to/ui5.yaml",
+ "\n",
+ "This project is now using SAPUI5 version 1.76.0",
+ "\n"
+ ];
+
+ t.is(t.context.processStdoutStub.callCount, expectedConsoleLog.length,
+ "console.log should be called " + expectedConsoleLog.length + " times");
+ expectedConsoleLog.forEach((expectedLog, i) => {
+ t.deepEqual(t.context.processStdoutStub.getCall(i).args, [expectedLog],
+ "console.log should be called with expected string on call index " + i);
+ });
+});
diff --git a/packages/cli/test/lib/cli/commands/versions.js b/packages/cli/test/lib/cli/commands/versions.js
new file mode 100644
index 00000000000..54b8a2ae9a9
--- /dev/null
+++ b/packages/cli/test/lib/cli/commands/versions.js
@@ -0,0 +1,58 @@
+import test from "ava";
+import sinon from "sinon";
+import path from "node:path";
+import versions from "../../../../lib/cli/commands/versions.js";
+const __dirname = path.join(import.meta.dirname, "..");
+
+test.afterEach.always((t) => {
+ sinon.restore();
+});
+
+test.serial("Retrieves version from package.json", (t) => {
+ const builderVersion = versions.getVersion("../../../test/fixtures/@ui5/builder");
+ const serverVersion = versions.getVersion("../../../test/fixtures/@ui5/server");
+ const fsVersion = versions.getVersion("../../../test/fixtures/@ui5/fs");
+ const projectVersion = versions.getVersion("../../../test/fixtures/@ui5/project");
+ const loggerVersion = versions.getVersion("../../../test/fixtures/@ui5/logger");
+
+ t.is(builderVersion, "0.2.6", "retrieved correct version for builder");
+ t.is(serverVersion, "0.2.2", "retrieved correct version for server");
+ t.is(fsVersion, "0.2.0", "retrieved correct version for fs");
+ t.is(projectVersion, "0.2.3", "retrieved correct version for project");
+ t.is(loggerVersion, "0.2.2", "retrieved correct version for logger");
+});
+
+test.serial("Retrieves version and package path in verbose mode", async (t) => {
+ const {setLogLevel} = await import("@ui5/logger");
+ setLogLevel("verbose");
+ const builderPath = "../../../test/fixtures/@ui5/builder";
+ const builderVersion = versions.getVersion(builderPath);
+ const serverPath = "../../../test/fixtures/@ui5/server";
+ const serverVersion = versions.getVersion(serverPath);
+ const fsPath = "../../../test/fixtures/@ui5/fs";
+ const fsVersion = versions.getVersion(fsPath);
+ const projectPath = "../../../test/fixtures/@ui5/project";
+ const projectVersion = versions.getVersion(projectPath);
+ const loggerPath = "../../../test/fixtures/@ui5/logger";
+ const loggerVersion = versions.getVersion(loggerPath);
+ t.is(builderVersion, `0.2.6 (from ${path.resolve(__dirname, builderPath)})`,
+ "retrieved correct version and path for builder");
+ t.is(serverVersion, `0.2.2 (from ${path.resolve(__dirname, serverPath)})`,
+ "retrieved correct version and path for server");
+ t.is(fsVersion, `0.2.0 (from ${path.resolve(__dirname, fsPath)})`,
+ "retrieved correct version and path for fs");
+ t.is(projectVersion, `0.2.3 (from ${path.resolve(__dirname, projectPath)})`,
+ "retrieved correct version and path for project");
+ t.is(loggerVersion, `0.2.2 (from ${path.resolve(__dirname, loggerPath)})`,
+ "retrieved correct version and path for logger");
+});
+
+test.serial("Error: returns not installed if version was not found", (t) => {
+ t.is(versions.getVersion("not/existing/path"), "===(not installed)", "No version found");
+});
+
+test.serial("Error: throws with error if error occurred while processing", async (t) => {
+ sinon.stub(versions, "getVersion").throws(new Error("Error occurred"));
+ const error = await t.throwsAsync(versions.handler({}));
+ t.is(error.message, "Error occurred", "Correct error message thrown");
+});
diff --git a/packages/cli/test/lib/cli/middlewares/base.js b/packages/cli/test/lib/cli/middlewares/base.js
new file mode 100644
index 00000000000..f062bfa6e83
--- /dev/null
+++ b/packages/cli/test/lib/cli/middlewares/base.js
@@ -0,0 +1,22 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+test.beforeEach(async (t) => {
+ t.context.initLogger = sinon.stub();
+ t.context.baseMiddleware = await esmock("../../../../lib/cli/middlewares/base.js", {
+ "../../../../lib/cli/middlewares/logger.js": {
+ initLogger: t.context.initLogger
+ }
+ });
+});
+
+test.afterEach("Stubs Cleanup", (t) => {
+ sinon.restore();
+});
+
+test.serial("uses default middleware", (t) => {
+ const {baseMiddleware, initLogger} = t.context;
+ baseMiddleware({loglevel: 1});
+ t.is(initLogger.called, true, "Logger middleware initialized");
+});
diff --git a/packages/cli/test/lib/cli/middlewares/logger.js b/packages/cli/test/lib/cli/middlewares/logger.js
new file mode 100644
index 00000000000..0727aa8d3d7
--- /dev/null
+++ b/packages/cli/test/lib/cli/middlewares/logger.js
@@ -0,0 +1,109 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import stripAnsi from "strip-ansi";
+
+test.beforeEach(async (t) => {
+ t.context.verboseLogStub = sinon.stub();
+ t.context.setLogLevelStub = sinon.stub();
+ t.context.isLogLevelEnabledStub = sinon.stub().returns(true);
+ t.context.getVersionStub = sinon.stub().returns("1.0.0");
+ t.context.logger = await esmock("../../../../lib/cli/middlewares/logger.js", {
+ "../../../../lib/cli/version.js": {
+ getVersion: t.context.getVersionStub
+ },
+ "@ui5/logger": {
+ getLogger: () => ({
+ verbose: t.context.verboseLogStub,
+ }),
+ setLogLevel: t.context.setLogLevelStub,
+ isLogLevelEnabled: t.context.isLogLevelEnabledStub,
+ }
+ });
+});
+
+test.serial("init logger", async (t) => {
+ const {logger, setLogLevelStub, isLogLevelEnabledStub, verboseLogStub, getVersionStub} = t.context;
+ await logger.initLogger({});
+ t.is(setLogLevelStub.callCount, 0, "setLevel has not been called");
+ t.is(isLogLevelEnabledStub.callCount, 1, "isLogLevelEnabled has been called once");
+ t.is(isLogLevelEnabledStub.firstCall.firstArg, "verbose",
+ "isLogLevelEnabled has been called with expected argument");
+ t.is(getVersionStub.callCount, 1, "getVersion has been called once");
+ t.is(verboseLogStub.callCount, 2, "log.verbose has been called twice");
+ t.is(verboseLogStub.firstCall.firstArg, "using @ui5/cli version 1.0.0",
+ "log.verbose has been called with expected argument on first call");
+ t.is(verboseLogStub.secondCall.firstArg, `using node version ${process.version}`,
+ "log.verbose has been called with expected argument on second call");
+});
+
+test.serial("With log-level flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({loglevel: "silly"});
+ t.is(setLogLevelStub.callCount, 1, "setLevel has been called once");
+ t.is(setLogLevelStub.getCall(0).args[0], "silly", "sets log level to silly");
+});
+
+test.serial("With default log-level flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({loglevel: "info"});
+ t.is(setLogLevelStub.callCount, 0, "setLevel has not been called");
+});
+
+test.serial("With verbose flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({verbose: true});
+ t.is(setLogLevelStub.callCount, 1, "setLevel has been called once");
+ t.is(setLogLevelStub.getCall(0).args[0], "verbose", "sets log level to verbose");
+});
+
+test.serial("With perf flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({perf: true});
+ t.is(setLogLevelStub.callCount, 1, "setLevel has been called once");
+ t.is(setLogLevelStub.getCall(0).args[0], "perf", "sets log level to perf");
+});
+
+test.serial("With silent flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({silent: true});
+ t.is(setLogLevelStub.callCount, 1, "setLevel has been called once");
+ t.is(setLogLevelStub.getCall(0).args[0], "silent", "sets log level to silent");
+});
+
+test.serial("With log-level and verbose flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({loglevel: "silly", verbose: true});
+ t.is(setLogLevelStub.callCount, 2, "setLevel has been called twice");
+ t.is(setLogLevelStub.getCall(0).args[0], "verbose", "sets log level to verbose");
+ t.is(setLogLevelStub.getCall(1).args[0], "silly", "sets log level to verbose");
+});
+
+test.serial("With log-level, verbose, perf and silent flag", async (t) => {
+ const {logger, setLogLevelStub} = t.context;
+ await logger.initLogger({loglevel: "silly", verbose: true, perf: true, silent: true});
+ t.is(setLogLevelStub.callCount, 4, "setLevel has been called four times");
+ t.is(setLogLevelStub.getCall(0).args[0], "silent", "sets log level to silent");
+ t.is(setLogLevelStub.getCall(1).args[0], "perf", "sets log level to perf");
+ t.is(setLogLevelStub.getCall(2).args[0], "verbose", "Third sets log level to verbose");
+ t.is(setLogLevelStub.getCall(3).args[0], "silly", "sets log level to verbose");
+});
+
+import path from "node:path";
+import {execa} from "execa";
+import {readFileSync} from "node:fs";
+
+const pkgJsonPath = new URL("../../../../package.json", import.meta.url);
+const pkg = JSON.parse(readFileSync(pkgJsonPath));
+const __dirname = import.meta.dirname;
+const ui5Cli = path.join(__dirname, "..", "..", "..", "..", "bin", "ui5.cjs");
+const ui5 = (args, options = {}) => execa(ui5Cli, args, options);
+
+test("ui5 --verbose", async (t) => {
+ // Using "versions" as a command, as the --verbose flag can't be used standalone
+ const {stderr} = await ui5(["versions", "--verbose"]);
+ // Debugger info is also included into the message. We need to exclude it
+ t.true(stripAnsi(stderr).includes(
+ `verb cli:middlewares:base using @ui5/cli version ${pkg.version} (from ${ui5Cli})\n`+
+ `verb cli:middlewares:base using node version ${process.version}`));
+});
diff --git a/packages/cli/test/lib/cli/version.js b/packages/cli/test/lib/cli/version.js
new file mode 100644
index 00000000000..4d41b97432a
--- /dev/null
+++ b/packages/cli/test/lib/cli/version.js
@@ -0,0 +1,12 @@
+import test from "ava";
+import {setVersion, getVersion} from "../../../lib/cli/version.js";
+
+test("Set and get version", (t) => {
+ t.is(getVersion(), undefined);
+
+ setVersion("1.2.3");
+ t.is(getVersion(), "1.2.3");
+
+ setVersion("4.5.6-foo.bar");
+ t.is(getVersion(), "4.5.6-foo.bar");
+});
diff --git a/packages/cli/test/lib/framework/add.js b/packages/cli/test/lib/framework/add.js
new file mode 100644
index 00000000000..0af5619edb8
--- /dev/null
+++ b/packages/cli/test/lib/framework/add.js
@@ -0,0 +1,608 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+function createMockProject(attr) {
+ return {
+ getName: () => attr.name,
+ getSpecVersion: () => {
+ return {
+ toString: () => attr.specVersion,
+ lt: () => attr.specVersion === "1.0",
+ };
+ },
+ getRootPath: () => attr.path,
+ getFrameworkName: () => attr.frameworkName,
+ getFrameworkVersion: () => attr.frameworkVersion,
+ getFrameworkDependencies: () => attr.frameworkLibraries || [],
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.getRootProjectConfigurationStub = sinon.stub();
+ t.context.getLibraryMetadataStub = sinon.stub();
+ t.context.createFrameworkResolverInstanceStub = sinon.stub().resolves({
+ getLibraryMetadata: t.context.getLibraryMetadataStub
+ });
+
+ t.context.updateYamlStub = sinon.stub();
+
+ t.context.addFramework = await esmock.p("../../../lib/framework/add.js", {
+ "../../../lib/framework/updateYaml.js": t.context.updateYamlStub,
+ "../../../lib/framework/utils.js": {
+ getRootProjectConfiguration: t.context.getRootProjectConfigurationStub,
+ createFrameworkResolverInstance: t.context.createFrameworkResolverInstanceStub
+ },
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.addFramework);
+});
+
+test.serial("Add without existing libraries in config", async (t) => {
+ const {addFramework, getRootProjectConfigurationStub, createFrameworkResolverInstanceStub,
+ getLibraryMetadataStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ getLibraryMetadataStub.resolves();
+
+ const result = await addFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: true}, "yamlUpdated should be true");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.is(getLibraryMetadataStub.callCount, 1, "Resolver.getLibraryMetadata should be called once");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ configPathOverride: undefined,
+ project,
+ data: {
+ framework: {libraries: [{name: "sap.ui.lib1"}]}
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Add with existing libraries in config", async (t) => {
+ const {addFramework, getRootProjectConfigurationStub, createFrameworkResolverInstanceStub,
+ getLibraryMetadataStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2"
+ }, {
+ name: "sap.ui.lib1"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ getLibraryMetadataStub.resolves();
+
+ const result = await addFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}, {name: "sap.ui.lib3"}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: true}, "yamlUpdated should be true");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.is(getLibraryMetadataStub.callCount, 2, "Resolver.getLibraryMetadata should be called twice");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args on first call");
+ t.deepEqual(getLibraryMetadataStub.getCall(1).args, ["sap.ui.lib3"],
+ "Resolver.getLibraryMetadata should be called with expected args on second call");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ configPathOverride: undefined,
+ project,
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.lib1"},
+ {name: "sap.ui.lib2"},
+ {name: "sap.ui.lib3"}
+ ]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Add optional with existing libraries in config", async (t) => {
+ const {addFramework, getRootProjectConfigurationStub, createFrameworkResolverInstanceStub,
+ getLibraryMetadataStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2",
+ development: true
+ }, {
+ name: "sap.ui.lib1",
+ development: true
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ getLibraryMetadataStub.resolves();
+
+ const result = await addFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1", optional: true}, {name: "sap.ui.lib3", optional: true}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: true}, "yamlUpdated should be true");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.is(getLibraryMetadataStub.callCount, 2, "Resolver.getLibraryMetadata should be called twice");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args on first call");
+ t.deepEqual(getLibraryMetadataStub.getCall(1).args, ["sap.ui.lib3"],
+ "Resolver.getLibraryMetadata should be called with expected args on second call");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ configPathOverride: undefined,
+ project,
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.lib1", optional: true},
+ {name: "sap.ui.lib2", development: true},
+ {name: "sap.ui.lib3", optional: true}
+ ]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Add with specVersion 1.0", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "1.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(addFramework({
+ projectGraphOptions
+ }));
+
+ t.is(error.message,
+ `ui5 add command requires specVersion "2.0" or higher. Project my-project uses specVersion "1.0"`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 0, "createFrameworkResolverInstanceStub should not be called");
+ t.is(getLibraryMetadataStub.callCount, 0, "Resolver.getLibraryMetadata should not be called");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Add without framework configuration", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(addFramework({
+ projectGraphOptions
+ }));
+
+ t.is(error.message, `Project my-project is missing a framework configuration. ` +
+ `Please use "ui5 use" to configure a framework and version.`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 0, "createFrameworkResolverInstanceStub should not be called");
+ t.is(getLibraryMetadataStub.callCount, 0, "Resolver.getLibraryMetadata should not be called");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Add without framework version configuration", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "OpenUI5"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(addFramework({
+ projectGraphOptions
+ }));
+
+ t.is(error.message, `Project my-project does not define a framework version configuration. ` +
+ `Please use "ui5 use" to configure a version.`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 0, "createFrameworkResolverInstanceStub should not be called");
+ t.is(getLibraryMetadataStub.callCount, 0, "Resolver.getLibraryMetadata should not be called");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Add with failing library metadata call", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ getLibraryMetadataStub.rejects(new Error("Failed to load library sap.ui.lib1"));
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(addFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ }));
+
+ t.is(error.message, `Failed to find SAPUI5 framework library sap.ui.lib1: Failed to load library sap.ui.lib1`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.is(getLibraryMetadataStub.callCount, 1, "Resolver.getLibraryMetadata should be called once");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args on first call");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Add with failing YAML update", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ const yamlUpdateError = new Error("Failed to update YAML file");
+ yamlUpdateError.name = "FrameworkUpdateYamlFailed";
+ updateYamlStub.rejects(yamlUpdateError);
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const result = await addFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: false}, "yamlUpdated should be false");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.is(getLibraryMetadataStub.callCount, 1, "Resolver.getLibraryMetadata should be called once");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args on first call");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ configPathOverride: undefined,
+ project,
+ data: {
+ framework: {
+ libraries: [{name: "sap.ui.lib1"}]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Add with failing YAML update (unexpected error)", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ updateYamlStub.rejects(new Error("Some unexpected error"));
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(addFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ }));
+
+ t.is(error.message, `Some unexpected error`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.is(getLibraryMetadataStub.callCount, 1, "Resolver.getLibraryMetadata should be called once");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args on first call");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ configPathOverride: undefined,
+ project,
+ data: {
+ framework: {
+ libraries: [{name: "sap.ui.lib1"}]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Add should not modify input parameters", async (t) => {
+ const {addFramework, getRootProjectConfigurationStub, createFrameworkResolverInstanceStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{"name": "sap.ui.lib1"}]
+ });
+
+ const libraries = [{name: "sap.ui.lib2"}];
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ await addFramework({
+ projectGraphOptions,
+ libraries
+ });
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+
+ t.deepEqual(libraries, [{name: "sap.ui.lib2"}], "libraries array should not be changed");
+});
+
+test.serial("Add with projectGraphOptions.config", async (t) => {
+ const {
+ addFramework,
+ getRootProjectConfigurationStub, createFrameworkResolverInstanceStub, getLibraryMetadataStub,
+ updateYamlStub
+ } = t.context;
+
+ const projectGraphOptions = {
+ config: "/path/to/ui5.yaml"
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const libraries = [{name: "sap.ui.lib1"}];
+ await addFramework({
+ projectGraphOptions,
+ libraries
+ });
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{config: "/path/to/ui5.yaml"}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(createFrameworkResolverInstanceStub.callCount, 1, "createFrameworkResolverInstanceStub should be called once");
+ t.deepEqual(createFrameworkResolverInstanceStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ }, {
+ cwd: "my-project-path"
+ }
+ ], "createFrameworkResolverInstance called with expected arguments");
+ t.is(getLibraryMetadataStub.callCount, 1, "Resolver.getLibraryMetadata should be called once");
+ t.deepEqual(getLibraryMetadataStub.getCall(0).args, ["sap.ui.lib1"],
+ "Resolver.getLibraryMetadata should be called with expected args on first call");
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: "/path/to/ui5.yaml",
+ data: {
+ framework: {
+ libraries: [{name: "sap.ui.lib1"}]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
diff --git a/packages/cli/test/lib/framework/remove.js b/packages/cli/test/lib/framework/remove.js
new file mode 100644
index 00000000000..754eccb1ec2
--- /dev/null
+++ b/packages/cli/test/lib/framework/remove.js
@@ -0,0 +1,410 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+function createMockProject(attr) {
+ return {
+ getName: () => attr.name,
+ getSpecVersion: () => {
+ return {
+ toString: () => attr.specVersion,
+ lt: () => attr.specVersion === "1.0",
+ };
+ },
+ getRootPath: () => attr.path,
+ getFrameworkName: () => attr.frameworkName,
+ getFrameworkVersion: () => attr.frameworkVersion,
+ getFrameworkDependencies: () => attr.frameworkLibraries || [],
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.getRootProjectConfigurationStub = sinon.stub();
+
+ t.context.updateYamlStub = sinon.stub();
+
+ t.context.logWarnStub = sinon.stub();
+
+ t.context.removeFramework = await esmock.p("../../../lib/framework/remove.js", {
+ "../../../lib/framework/updateYaml.js": t.context.updateYamlStub,
+ "../../../lib/framework/utils.js": {
+ getRootProjectConfiguration: t.context.getRootProjectConfigurationStub
+ },
+ "@ui5/logger": {
+ getLogger: sinon.stub().returns({
+ warn: t.context.logWarnStub
+ })
+ }
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.removeFramework);
+});
+
+test.serial("Remove with existing libraries in config", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2"
+ }, {
+ name: "sap.ui.lib1"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+
+ const result = await removeFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: true}, "yamlUpdated should be true");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {libraries: [{name: "sap.ui.lib2"}]}
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Remove with 2 existing libraries in config", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2"
+ }, {
+ name: "sap.ui.lib1"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const result = await removeFramework({
+ projectGraphOptions,
+ libraries: [{
+ name: "sap.ui.lib1"
+ }, {
+ name: "sap.ui.lib2"
+ }]
+ });
+
+ t.deepEqual(result, {yamlUpdated: true}, "yamlUpdated should be true");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {libraries: []}
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+
+test.serial("Remove with non-existing library in config", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub, logWarnStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib1"
+ }, {
+ name: "sap.ui.lib2"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ await removeFramework({
+ projectGraphOptions,
+ libraries: [{
+ name: "sap.ui.nonexisting"
+ }]
+ });
+
+ t.is(logWarnStub.callCount, 1, "logger called once");
+
+ t.deepEqual(logWarnStub.getCall(0).args,
+ [`Failed to remove framework library sap.ui.nonexisting from project my-project because it is not present.`]);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ libraries: [{
+ name: "sap.ui.lib1"
+ }, {
+ name: "sap.ui.lib2"
+ }]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Remove with specVersion 1.0", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "1.0",
+ name: "my-project",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(removeFramework({
+ projectGraphOptions
+ }));
+
+ t.is(error.message,
+ `ui5 remove command requires specVersion "2.0" or higher. Project my-project uses specVersion "1.0"`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Remove without framework configuration", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(removeFramework({
+ projectGraphOptions
+ }));
+
+ t.is(error.message, `Project my-project is missing a framework configuration. ` +
+ `Please use "ui5 use" to configure a framework and version.`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Remove without framework version configuration", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(removeFramework({
+ projectGraphOptions
+ }));
+
+ t.is(error.message, `Project my-project does not define a framework version configuration. ` +
+ `Please use "ui5 use" to configure a version.`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Remove with failing YAML update", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const yamlUpdateError = new Error("Failed to update YAML file");
+ yamlUpdateError.name = "FrameworkUpdateYamlFailed";
+ updateYamlStub.rejects(yamlUpdateError);
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2"
+ }, {
+ name: "sap.ui.lib1"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const result = await removeFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: false}, "yamlUpdated should be false");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ libraries: [{name: "sap.ui.lib2"}]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Remove with failing YAML update (unexpected error)", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ updateYamlStub.rejects(new Error("Some unexpected error"));
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2"
+ }, {
+ name: "sap.ui.lib1"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(removeFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ }));
+
+ t.is(error.message, `Some unexpected error`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ libraries: [{name: "sap.ui.lib2"}]
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Remove with projectGraphOptions.config", async (t) => {
+ const {removeFramework, getRootProjectConfigurationStub, updateYamlStub} = t.context;
+
+ const projectGraphOptions = {
+ config: "/path/to/ui5.yaml"
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0",
+ frameworkLibraries: [{
+ name: "sap.ui.lib2"
+ }, {
+ name: "sap.ui.lib1"
+ }]
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+
+ const result = await removeFramework({
+ projectGraphOptions,
+ libraries: [{name: "sap.ui.lib1"}]
+ });
+
+ t.deepEqual(result, {yamlUpdated: true}, "yamlUpdated should be true");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{config: "/path/to/ui5.yaml"}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: "/path/to/ui5.yaml",
+ data: {
+ framework: {libraries: [{name: "sap.ui.lib2"}]}
+ }
+ }], "updateYaml should be called with expected args");
+});
diff --git a/packages/cli/test/lib/framework/updateYaml.js b/packages/cli/test/lib/framework/updateYaml.js
new file mode 100644
index 00000000000..16a6f457b4f
--- /dev/null
+++ b/packages/cli/test/lib/framework/updateYaml.js
@@ -0,0 +1,993 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import path from "node:path";
+
+let updateYaml;
+
+test.beforeEach(async (t) => {
+ t.context.fsReadFileStub = sinon.stub();
+ t.context.fsWriteFileStub = sinon.stub().resolves();
+ updateYaml = await esmock("../../../lib/framework/updateYaml", {
+ "node:fs/promises": {
+ readFile: t.context.fsReadFileStub,
+ writeFile: t.context.fsWriteFileStub
+ }
+ });
+});
+
+test.afterEach.always(() => {
+ sinon.restore();
+});
+
+test.serial("Should update single document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+---
+metadata:
+ name: my-project
+framework:
+ name: SAPUI5
+ version: 1.0.0
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+---
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should update first document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+specVersion: "2.0"
+metadata:
+ name: my-project
+framework:
+ name: SAPUI5
+ version: 1.0.0
+---
+specVersion: "1.0"
+kind: extension
+metadata:
+ name: my-extension
+type: project-shim
+shims:
+ configurations: {}
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+specVersion: "2.0"
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+---
+specVersion: "1.0"
+kind: extension
+metadata:
+ name: my-extension
+type: project-shim
+shims:
+ configurations: {}
+`, "writeFile should be called with expected content");
+});
+
+
+test.serial("Should update second document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+specVersion: "1.0"
+kind: extension
+metadata:
+ name: my-extension
+type: project-shim
+shims:
+ configurations: {}
+framework:
+ name: SAPUI5
+ version: 1.0.0
+---
+specVersion: "2.0"
+metadata:
+ name: my-project
+framework:
+ name: SAPUI5
+ version: 1.0.0
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+specVersion: "1.0"
+kind: extension
+metadata:
+ name: my-extension
+type: project-shim
+shims:
+ configurations: {}
+framework:
+ name: SAPUI5
+ version: 1.0.0
+---
+specVersion: "2.0"
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new object with one property to document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new object with two properties to document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add version property to document and keep name", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: "OpenUI5"
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: "OpenUI5"
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add name property to document and keep version", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ version: 1.76.0
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ version: 1.76.0
+ name: OpenUI5
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array to document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array to document with empty array", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ []
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should remove array from document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: []
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should remove array from document with content below", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: []
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array to document with content below", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array to document with content separated by empty line below", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array element to document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array elements to document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ {name: "sap.ui.layout"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+ - name: sap.ui.layout
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array elements to document with content below", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ {name: "sap.ui.layout"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+ - name: sap.ui.layout
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array elements to document with content below on same level", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ libraries:
+ - name: sap.ui.core
+ version: "1.76.0"
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ {name: "sap.ui.layout"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+ - name: sap.ui.layout
+ version: "1.76.0"
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array elements to document with content separated by empty line below", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core"},
+ {name: "sap.m"},
+ {name: "sap.ui.layout"},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ - name: sap.m
+ - name: sap.ui.layout
+resources:
+ configuration:
+ propertiesFileSourceEncoding: UTF-8
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should add new array elements with multiple properties to document", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ development: true
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ libraries: [
+ {name: "sap.ui.core", optional: true},
+ {name: "sap.m", optional: true},
+ {name: "sap.ui.layout", optional: true},
+ ]
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+ libraries:
+ - name: sap.ui.core
+ optional: true
+ - name: sap.m
+ optional: true
+ - name: sap.ui.layout
+ optional: true
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Should validate YAML before writing file", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework: { name: "SAPUI5" }
+`); // Using JSON object notation is currently not supported
+
+ const error = await t.throwsAsync(updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ name: "SAPUI5",
+ version: "1.76.0"
+ }
+ }
+ }));
+
+ t.is(error.message,
+ `Failed to update YAML file: bad indentation of a mapping entry (5:14)\n` +
+ `\n` +
+ ` 2 | metadata:\n` +
+ ` 3 | name: my-project\n` +
+ ` 4 | framework: { name: "SAPUI5" }\n` +
+ ` 5 | version: "1.76.0"\n` +
+ `------------------^`
+ );
+ t.is(t.context.fsWriteFileStub.callCount, 0, "fs.writeFile should not be called");
+});
+
+test.serial("Should throw error when project document can't be found", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project-1
+---
+metadata:
+ name: my-project-2
+`);
+
+ const error = await t.throwsAsync(updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project-3"
+ },
+ configPathOverride: "ui5.yaml",
+ data: {}
+ }));
+
+ t.is(error.message,
+ `Could not find project with name my-project-3 in YAML: ${path.join("my-project", "ui5.yaml")}`);
+ t.is(t.context.fsWriteFileStub.callCount, 0, "fs.writeFile should not be called");
+});
+
+test.serial("Should add version property to object", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ libraries:
+ - name: sap.ui.core
+something: else
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ data: {
+ framework: {
+ version: "1.85.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "ui5.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ libraries:
+ - name: sap.ui.core
+ version: "1.85.0"
+something: else
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Relative configPathOverride", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+---
+metadata:
+ name: my-project
+framework:
+ name: SAPUI5
+ version: 1.0.0
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ configPathOverride: path.join("dir", "other-file.yaml"),
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsReadFileStub.callCount, 1, "fs.readFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "dir", "other-file.yaml"),
+ "readFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("my-project", "dir", "other-file.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+---
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
+
+test.serial("Absolute configPathOverride", async (t) => {
+ t.context.fsReadFileStub.resolves(`
+---
+metadata:
+ name: my-project
+framework:
+ name: SAPUI5
+ version: 1.0.0
+`);
+
+ await updateYaml({
+ project: {
+ getRootPath: () => "my-project",
+ getName: () => "my-project"
+ },
+ configPathOverride: path.join("/", "dir", "other-file.yaml"),
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ });
+
+ t.is(t.context.fsReadFileStub.callCount, 1, "fs.readFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("/", "dir", "other-file.yaml"),
+ "readFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.callCount, 1, "fs.writeFile should be called once");
+ t.deepEqual(t.context.fsWriteFileStub.getCall(0).args[0], path.join("/", "dir", "other-file.yaml"),
+ "writeFile should be called with expected path");
+ t.is(t.context.fsWriteFileStub.getCall(0).args[1], `
+---
+metadata:
+ name: my-project
+framework:
+ name: OpenUI5
+ version: "1.76.0"
+`, "writeFile should be called with expected content");
+});
diff --git a/packages/cli/test/lib/framework/use.js b/packages/cli/test/lib/framework/use.js
new file mode 100644
index 00000000000..00fa98eb070
--- /dev/null
+++ b/packages/cli/test/lib/framework/use.js
@@ -0,0 +1,686 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+
+function createMockProject(attr) {
+ return {
+ getName: () => attr.name,
+ getSpecVersion: () => {
+ return {
+ toString: () => attr.specVersion,
+ lt: () => attr.specVersion === "1.0",
+ };
+ },
+ getRootPath: () => attr.path,
+ getFrameworkName: () => attr.frameworkName,
+ getFrameworkVersion: () => attr.frameworkVersion,
+ };
+}
+
+test.beforeEach(async (t) => {
+ t.context.getRootProjectConfigurationStub = sinon.stub();
+ t.context.frameworkResolverResolveVersionStub = sinon.stub();
+ t.context.updateYamlStub = sinon.stub();
+ t.context.useFramework = await esmock.p("../../../lib/framework/use.js", {
+ "../../../lib/framework/updateYaml.js": t.context.updateYamlStub,
+ "../../../lib/framework/utils.js": {
+ getRootProjectConfiguration: t.context.getRootProjectConfigurationStub,
+ frameworkResolverResolveVersion: t.context.frameworkResolverResolveVersionStub
+ },
+ });
+});
+
+test.afterEach.always((t) => {
+ sinon.restore();
+ esmock.purge(t.context.useFramework);
+});
+
+test.serial("Use with name and version (OpenUI5)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "openui5",
+ version: "latest"
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "OpenUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with name and version (SAPUI5)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "sapui5",
+ version: "latest"
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "SAPUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with version only (OpenUI5)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "OpenUI5"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: null,
+ version: "latest"
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "OpenUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with version only (SAPUI5)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "SAPUI5"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: null,
+ version: "latest"
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "SAPUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with name only (no existing framework configuration)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "SAPUI5",
+ version: null
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "SAPUI5",
+ usedVersion: null,
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 0, "frameworkResolverResolveVersion should not be called");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "SAPUI5"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with name only (existing framework configuration)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ frameworkName: "OpenUI5",
+ frameworkVersion: "1.76.0"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "SAPUI5",
+ version: null
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "1.76.0"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "SAPUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with projectGraphOptions.config", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const projectGraphOptions = {
+ config: "/path/to/ui5.yaml"
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path"
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "SAPUI5",
+ version: "latest"
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "SAPUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: true
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{config: "/path/to/ui5.yaml"}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "SAPUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: "/path/to/ui5.yaml",
+ data: {
+ framework: {
+ name: "SAPUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with version only (no framework name)", async (t) => {
+ const {getRootProjectConfigurationStub,
+ frameworkResolverResolveVersionStub, updateYamlStub, useFramework} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: null,
+ version: "latest"
+ }
+ }));
+
+ t.is(error.message, "No framework configuration defined. Make sure to also provide the framework name.");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 0, "frameworkResolverResolveVersion should not be called");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Use with invalid name", async (t) => {
+ const {getRootProjectConfigurationStub,
+ frameworkResolverResolveVersionStub, updateYamlStub, useFramework} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "Foo",
+ version: "latest"
+ }
+ }));
+
+ t.is(error.message, "Invalid framework name: Foo");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 0, "frameworkResolverResolveVersion should not be called");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Use with specVersion 1.0", async (t) => {
+ const {getRootProjectConfigurationStub,
+ frameworkResolverResolveVersionStub, updateYamlStub, useFramework} = t.context;
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "1.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+
+ const error = await t.throwsAsync(useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "Foo",
+ version: "latest"
+ }
+ }));
+
+ t.is(error.message,
+ `ui5 use command requires specVersion "2.0" or higher. Project my-project uses specVersion "1.0"`);
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 0, "frameworkResolverResolveVersion should not be called");
+
+ t.is(updateYamlStub.callCount, 0, "updateYaml should not be called");
+});
+
+test.serial("Use with name and version (YAML update fails)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ const yamlUpdateError = new Error("Failed to update YAML file");
+ yamlUpdateError.name = "FrameworkUpdateYamlFailed";
+ updateYamlStub.rejects(yamlUpdateError);
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const result = await useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "openui5",
+ version: "latest"
+ }
+ });
+
+ t.deepEqual(result, {
+ usedFramework: "OpenUI5",
+ usedVersion: "1.76.0",
+ yamlUpdated: false
+ }, "useFramework should return expected result object");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
+
+test.serial("Use with name and version (YAML update fails with unexpected error)", async (t) => {
+ const {
+ getRootProjectConfigurationStub, frameworkResolverResolveVersionStub,
+ updateYamlStub, useFramework
+ } = t.context;
+
+ updateYamlStub.rejects(new Error("Some unexpected error"));
+
+ const projectGraphOptions = {
+ fakeProjectGraphOptions: true
+ };
+
+ const project = createMockProject({
+ specVersion: "2.0",
+ name: "my-project",
+ path: "my-project-path",
+ });
+
+ getRootProjectConfigurationStub.resolves(project);
+ frameworkResolverResolveVersionStub.resolves("1.76.0");
+
+ const error = await t.throwsAsync(useFramework({
+ projectGraphOptions,
+ frameworkOptions: {
+ name: "openui5",
+ version: "latest"
+ }
+ }));
+
+ t.is(error.message, "Some unexpected error");
+
+ t.is(getRootProjectConfigurationStub.callCount, 1, "generateProjectGraph should be called once");
+ t.deepEqual(getRootProjectConfigurationStub.getCall(0).args, [{fakeProjectGraphOptions: true}],
+ "generateProjectGraph should be called with expected args");
+
+ t.is(frameworkResolverResolveVersionStub.callCount, 1, "frameworkResolverResolveVersion should be called once");
+ t.deepEqual(frameworkResolverResolveVersionStub.getCall(0).args, [
+ {
+ frameworkName: "OpenUI5",
+ frameworkVersion: "latest"
+ },
+ {
+ cwd: "my-project-path"
+ }
+ ], "frameworkResolverResolveVersion should be called with expected args");
+
+ t.is(updateYamlStub.callCount, 1, "updateYaml should be called once");
+ t.deepEqual(updateYamlStub.getCall(0).args, [{
+ project,
+ configPathOverride: undefined,
+ data: {
+ framework: {
+ name: "OpenUI5",
+ version: "1.76.0"
+ }
+ }
+ }], "updateYaml should be called with expected args");
+});
diff --git a/packages/cli/test/lib/framework/utils.js b/packages/cli/test/lib/framework/utils.js
new file mode 100644
index 00000000000..0ac6f4aaf37
--- /dev/null
+++ b/packages/cli/test/lib/framework/utils.js
@@ -0,0 +1,297 @@
+import test from "ava";
+import sinonGlobal from "sinon";
+import esmock from "esmock";
+import path from "node:path";
+
+test.beforeEach(async (t) => {
+ // Tests either rely on not having UI5_DATA_DIR defined, or explicitly define it
+ t.context.originalUi5DataDirEnv = process.env.UI5_DATA_DIR;
+ delete process.env.UI5_DATA_DIR;
+
+ const sinon = t.context.sinon = sinonGlobal.createSandbox();
+
+ t.context.graph = {
+ getRoot: sinon.stub().returns({})
+ };
+
+ t.context.graphFromStaticFile = sinon.stub().resolves(t.context.graph),
+ t.context.graphFromPackageDependencies = sinon.stub().resolves(t.context.graph);
+
+ t.context.Sapui5Resolver = sinon.stub();
+ t.context.Openui5Resolver = sinon.stub();
+ t.context.Sapui5MavenSnapshotResolver = sinon.stub();
+
+ t.context.ConfigurationGetUi5DataDirStub = sinon.stub().returns(undefined);
+ t.context.ConfigurationStub = {
+ fromFile: sinon.stub().resolves({
+ getUi5DataDir: t.context.ConfigurationGetUi5DataDirStub
+ })
+ };
+
+ t.context.utils = await esmock.p("../../../lib/framework/utils.js", {
+ "@ui5/project/graph": {
+ graphFromStaticFile: t.context.graphFromStaticFile,
+ graphFromPackageDependencies: t.context.graphFromPackageDependencies
+ },
+ "@ui5/project/ui5Framework/Sapui5Resolver": {
+ default: t.context.Sapui5Resolver
+ },
+ "@ui5/project/ui5Framework/Openui5Resolver": {
+ default: t.context.Openui5Resolver
+ },
+ "@ui5/project/ui5Framework/Sapui5MavenSnapshotResolver": {
+ default: t.context.Sapui5MavenSnapshotResolver
+ },
+ "@ui5/project/config/Configuration": t.context.ConfigurationStub
+ });
+ t.context._utils = t.context.utils._utils;
+});
+
+test.afterEach.always((t) => {
+ // Reset UI5_DATA_DIR env
+ if (typeof t.context.originalUi5DataDirEnv === "undefined") {
+ delete process.env.UI5_DATA_DIR;
+ } else {
+ process.env.UI5_DATA_DIR = t.context.originalUi5DataDirEnv;
+ }
+ t.context.sinon.restore();
+ esmock.purge(t.context.utils);
+});
+
+test.serial("getRootProjectConfiguration: dependencyDefinition", async (t) => {
+ const {getRootProjectConfiguration} = t.context.utils;
+ const {graphFromStaticFile, graphFromPackageDependencies} = t.context;
+
+ const result = await getRootProjectConfiguration({
+ dependencyDefinition: "foo"
+ });
+
+ t.is(graphFromStaticFile.callCount, 1);
+ t.deepEqual(graphFromStaticFile.getCall(0).args, [{
+ filePath: "foo",
+ resolveFrameworkDependencies: false
+ }]);
+
+ t.is(graphFromPackageDependencies.callCount, 0);
+
+ t.is(t.context.graph.getRoot.callCount, 1);
+ t.deepEqual(t.context.graph.getRoot.getCall(0).args, []);
+
+ t.is(result, t.context.graph.getRoot.getCall(0).returnValue);
+});
+
+test.serial("getRootProjectConfiguration: config", async (t) => {
+ const {getRootProjectConfiguration} = t.context.utils;
+ const {graphFromStaticFile, graphFromPackageDependencies} = t.context;
+
+ const result = await getRootProjectConfiguration({
+ config: "foo"
+ });
+
+ t.is(graphFromPackageDependencies.callCount, 1);
+ t.deepEqual(graphFromPackageDependencies.getCall(0).args, [{
+ rootConfigPath: "foo",
+ resolveFrameworkDependencies: false
+ }]);
+
+ t.is(graphFromStaticFile.callCount, 0);
+
+ t.is(t.context.graph.getRoot.callCount, 1);
+ t.deepEqual(t.context.graph.getRoot.getCall(0).args, []);
+
+ t.is(result, t.context.graph.getRoot.getCall(0).returnValue);
+});
+
+test.serial("getFrameworkResolver: SAPUI5", async (t) => {
+ const {getFrameworkResolver} = t.context._utils;
+ const {Sapui5Resolver} = t.context;
+
+ const result = await getFrameworkResolver("SAPUI5", "1.100.0");
+ t.is(result, Sapui5Resolver);
+});
+
+test.serial("getFrameworkResolver: OpenUI5", async (t) => {
+ const {getFrameworkResolver} = t.context._utils;
+ const {Openui5Resolver} = t.context;
+
+ const result = await getFrameworkResolver("OpenUI5", "1.100.0");
+ t.is(result, Openui5Resolver);
+});
+
+test.serial("getFrameworkResolver: OpenUI5 Snapshot", async (t) => {
+ const {getFrameworkResolver} = t.context._utils;
+ const {Sapui5MavenSnapshotResolver} = t.context;
+
+ const result = await getFrameworkResolver("OpenUI5", "1.100.0-SNAPSHOT");
+ t.is(result, Sapui5MavenSnapshotResolver);
+});
+
+test.serial("getFrameworkResolver: SAPUI5 Snapshot", async (t) => {
+ const {getFrameworkResolver} = t.context._utils;
+ const {Sapui5MavenSnapshotResolver} = t.context;
+
+ const result = await getFrameworkResolver("SAPUI5", "1.100.0-SNAPSHOT");
+ t.is(result, Sapui5MavenSnapshotResolver);
+});
+
+test.serial("getFrameworkResolver: Invalid framework.name", async (t) => {
+ const {getFrameworkResolver} = t.context._utils;
+
+ await t.throwsAsync(() => getFrameworkResolver("UI5", "1.100.0"), {
+ message: "Invalid framework.name: UI5"
+ });
+});
+
+test.serial("createFrameworkResolverInstance: Without ui5DataDir", async (t) => {
+ const {createFrameworkResolverInstance} = t.context.utils;
+ const {sinon} = t.context;
+
+ const ResolverStub = sinon.stub().returns({});
+ sinon.stub(t.context._utils, "getFrameworkResolver").resolves(ResolverStub);
+ sinon.stub(t.context._utils, "getUi5DataDir").resolves(undefined);
+
+ const result = await createFrameworkResolverInstance({
+ frameworkName: "",
+ frameworkVersion: ""
+ }, {
+ cwd: "my-project-path"
+ });
+
+ t.is(t.context._utils.getFrameworkResolver.callCount, 1);
+ t.deepEqual(t.context._utils.getFrameworkResolver.getCall(0).args, [
+ "",
+ ""
+ ]);
+
+ t.is(t.context._utils.getUi5DataDir.callCount, 1);
+ t.deepEqual(t.context._utils.getUi5DataDir.getCall(0).args, [
+ {
+ cwd: "my-project-path"
+ }
+ ]);
+
+ t.is(ResolverStub.callCount, 1);
+ t.is(result, ResolverStub.getCall(0).returnValue);
+ t.true(ResolverStub.alwaysCalledWithNew());
+ t.deepEqual(ResolverStub.getCall(0).args, [
+ {
+ cwd: "my-project-path",
+ version: "",
+ ui5DataDir: undefined
+ }
+ ]);
+});
+
+test.serial("createFrameworkResolverInstance: With ui5DataDir", async (t) => {
+ const {createFrameworkResolverInstance} = t.context.utils;
+ const {sinon} = t.context;
+
+ const ResolverStub = sinon.stub().returns({});
+ sinon.stub(t.context._utils, "getFrameworkResolver").resolves(ResolverStub);
+ sinon.stub(t.context._utils, "getUi5DataDir").resolves("my-ui5-data-dir");
+
+ const result = await createFrameworkResolverInstance({
+ frameworkName: "",
+ frameworkVersion: ""
+ }, {
+ cwd: "my-project-path"
+ });
+
+ t.is(t.context._utils.getFrameworkResolver.callCount, 1);
+ t.deepEqual(t.context._utils.getFrameworkResolver.getCall(0).args, [
+ "",
+ ""
+ ]);
+
+ t.is(t.context._utils.getUi5DataDir.callCount, 1);
+ t.deepEqual(t.context._utils.getUi5DataDir.getCall(0).args, [
+ {
+ cwd: "my-project-path"
+ }
+ ]);
+
+ t.is(ResolverStub.callCount, 1);
+ t.is(result, ResolverStub.getCall(0).returnValue);
+ t.true(ResolverStub.alwaysCalledWithNew());
+ t.deepEqual(ResolverStub.getCall(0).args, [
+ {
+ cwd: "my-project-path",
+ version: "",
+ ui5DataDir: "my-ui5-data-dir"
+ }
+ ]);
+});
+
+test.serial("frameworkResolverResolveVersion", async (t) => {
+ const {frameworkResolverResolveVersion} = t.context.utils;
+ const {sinon} = t.context;
+
+ const resolveVersionStub = sinon.stub().resolves("1.111.1");
+ sinon.stub(t.context._utils, "getFrameworkResolver").resolves({
+ resolveVersion: resolveVersionStub
+ });
+ sinon.stub(t.context._utils, "getUi5DataDir").resolves(undefined);
+
+ const result = await frameworkResolverResolveVersion({
+ frameworkName: "SAPUI5",
+ frameworkVersion: "latest"
+ }, {
+ cwd: "my-project-path"
+ });
+
+ t.is(result, "1.111.1");
+
+ t.is(resolveVersionStub.callCount, 1);
+ t.deepEqual(resolveVersionStub.getCall(0).args, [
+ "latest",
+ {
+ cwd: "my-project-path",
+ ui5DataDir: undefined
+ }
+ ]);
+});
+
+test.serial("getUi5DataDir: no value defined", async (t) => {
+ const {ConfigurationGetUi5DataDirStub} = t.context;
+ const {getUi5DataDir} = t.context._utils;
+
+ const result = await getUi5DataDir({
+ cwd: path.resolve("foo")
+ });
+
+ t.is(result, undefined);
+
+ t.is(ConfigurationGetUi5DataDirStub.callCount, 1);
+});
+
+test.serial("getUi5DataDir: from environment variable", async (t) => {
+ const {ConfigurationGetUi5DataDirStub} = t.context;
+ const {getUi5DataDir} = t.context._utils;
+
+ // Environment variable must be preferred over configuration value
+ ConfigurationGetUi5DataDirStub.returns(".ui5-data-dir-from-configuration");
+ process.env.UI5_DATA_DIR = ".ui5-data-dir-from-env-variable";
+
+ const result = await getUi5DataDir({
+ cwd: path.resolve("foo")
+ });
+
+ t.is(result, path.join(path.resolve("foo"), ".ui5-data-dir-from-env-variable"));
+
+ t.is(ConfigurationGetUi5DataDirStub.callCount, 0);
+});
+
+test.serial("getUi5DataDir: from Configuration", async (t) => {
+ const {ConfigurationGetUi5DataDirStub} = t.context;
+ const {getUi5DataDir} = t.context._utils;
+
+ ConfigurationGetUi5DataDirStub.returns(".ui5-data-dir-from-configuration");
+
+ const result = await getUi5DataDir({
+ cwd: path.resolve("foo")
+ });
+
+ t.is(result, path.join(path.resolve("foo"), ".ui5-data-dir-from-configuration"));
+
+ t.is(ConfigurationGetUi5DataDirStub.callCount, 1);
+});
diff --git a/packages/cli/test/lib/init/init.js b/packages/cli/test/lib/init/init.js
new file mode 100644
index 00000000000..c47dcfe0f09
--- /dev/null
+++ b/packages/cli/test/lib/init/init.js
@@ -0,0 +1,112 @@
+import test from "ava";
+import init from "../../../lib/init/init.js";
+import {fileURLToPath} from "node:url";
+import sinon from "sinon";
+import esmock from "esmock";
+
+function getFixturePath(fixtureName) {
+ return fileURLToPath(new URL("../../fixtures/init/" + fixtureName, import.meta.url));
+}
+
+test.afterEach.always(() => {
+ sinon.restore();
+});
+
+test("Init for application", async (t) => {
+ const projectConfig = await init({
+ cwd: getFixturePath("application")
+ });
+
+ t.deepEqual(projectConfig, {
+ specVersion: "4.0",
+ type: "application",
+ metadata: {
+ name: "init-application"
+ }
+ });
+});
+
+test("Init for library", async (t) => {
+ const projectConfig = await init({
+ cwd: getFixturePath("library")
+ });
+
+ t.deepEqual(projectConfig, {
+ specVersion: "4.0",
+ type: "library",
+ metadata: {
+ name: "init-library"
+ }
+ });
+});
+
+const GENERAL_ERROR_MESSAGE = `Applications should only have a 'webapp' folder.
+Libraries should only have an 'src' and (optional) 'test' folder.
+
+If you are about to start a new project, please refer to:
+https://ui5.github.io/cli/v4/pages/GettingStarted/#starting-a-new-project`;
+
+test("Init for invalid project (Found 'webapp', 'src' and 'test' folders)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid-webapp-src-test")
+ }), {message:
+ "Could not detect project type: Found 'webapp', 'src' and 'test' folders.\n" +
+ GENERAL_ERROR_MESSAGE});
+});
+
+test("Init for invalid project (Found 'webapp' and 'src' folders)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid-webapp-src")
+ }), {message:
+ "Could not detect project type: Found 'webapp' and 'src' folders.\n" +
+ GENERAL_ERROR_MESSAGE});
+});
+
+test("Init for invalid project (Found 'webapp' and 'test' folders)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid-webapp-test")
+ }), {message:
+ "Could not detect project type: Found 'webapp' and 'test' folders.\n" +
+ GENERAL_ERROR_MESSAGE});
+});
+
+test("Init for invalid project (Found 'test' folder but no 'src' folder)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid-test")
+ }), {message:
+ "Could not detect project type: Found 'test' folder but no 'src' folder.\n" +
+ GENERAL_ERROR_MESSAGE});
+});
+
+test("Init for invalid project (Could not find 'webapp' or 'src' / 'test' folders)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid")
+ }), {message:
+ "Could not detect project type: Could not find 'webapp' or 'src' / 'test' folders.\n" +
+ GENERAL_ERROR_MESSAGE});
+});
+
+test("Init for invalid project (No package.json)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid-no-package-json")
+ }), {message: "Initialization not possible: Missing package.json file"});
+});
+
+test("Init for invalid project (Missing 'name' in package.json)", async (t) => {
+ await t.throwsAsync(init({
+ cwd: getFixturePath("invalid-missing-package-name")
+ }), {message: "Initialization not possible: Missing 'name' in package.json"});
+});
+
+test.serial("Init with default arguments (throws fs.readFile error)", async (t) => {
+ const fsReadFileStub = sinon.stub().withArgs("package.json", "utf8")
+ .rejects(new Error("Some error from fs.readFile"));
+ const init = await esmock("../../../lib/init/init", {
+ "node:fs/promises": {
+ readFile: fsReadFileStub
+ }
+ });
+ await t.throwsAsync(init(), {
+ message: "Some error from fs.readFile"
+ });
+});
diff --git a/packages/cli/test/lib/package-exports.js b/packages/cli/test/lib/package-exports.js
new file mode 100644
index 00000000000..cba029a1034
--- /dev/null
+++ b/packages/cli/test/lib/package-exports.js
@@ -0,0 +1,24 @@
+import test from "ava";
+import {createRequire} from "node:module";
+
+// Using CommonsJS require since JSON module imports are still experimental
+const require = createRequire(import.meta.url);
+
+// package.json should be exported to allow reading the version
+test("export of package.json", (t) => {
+ t.truthy(require("@ui5/cli/package.json").version);
+});
+
+test("export of bin/ui5.cjs", (t) => {
+ t.truthy(import.meta.resolve("@ui5/cli/bin/ui5.cjs"));
+});
+
+test("export of bin/ui5.js (for compatibility with CLI v2 that might invoke a newer local installation", (t) => {
+ t.truthy(import.meta.resolve("@ui5/cli/bin/ui5.js"));
+});
+
+// Check number of definied exports
+test("check number of exports", (t) => {
+ const packageJson = require("@ui5/cli/package.json");
+ t.is(Object.keys(packageJson.exports).length, 3);
+});
diff --git a/packages/cli/test/lib/utils/fsHelper.js b/packages/cli/test/lib/utils/fsHelper.js
new file mode 100644
index 00000000000..78da9e4306c
--- /dev/null
+++ b/packages/cli/test/lib/utils/fsHelper.js
@@ -0,0 +1,42 @@
+import test from "ava";
+import sinon from "sinon";
+import esmock from "esmock";
+import {exists, pathsExist} from "../../../lib/utils/fsHelper.js";
+
+test.afterEach.always(() => {
+ sinon.restore();
+});
+
+test("Returns true if directory or file exists", async (t) => {
+ t.is(await exists("./test/fixtures/init/application/ui5.yaml"), true, "ui5.yaml found in path");
+ t.is(await exists("./test/fixtures/init"), true, "directory exists in path");
+});
+
+test("Returns true if list of paths exist", async (t) => {
+ t.deepEqual(await pathsExist(["src", "test"], "./test/fixtures/init/library"), [true, true], "paths do exist");
+});
+
+test("Returns false if ui5.yaml was not found or directory does not exist", async (t) => {
+ t.is(await exists("./test/fixtures/init/invalid/ui5.yaml"), false, "ui5.yaml was not found in path");
+ t.is(await exists("./path/does/not/exist"), false, "directory does not exist");
+});
+
+test("Returns results of multiple paths", async (t) => {
+ t.deepEqual(await pathsExist(["src", "test", "notExists"], "./test/fixtures/init/library"),
+ [true, true, false], "some paths do exist");
+});
+
+test.serial("Throws in case of fs.stat error", async (t) => {
+ const fsStatStub = sinon.stub().rejects(new Error("Some fs.stat error"));
+ const {exists, pathsExist} = await esmock("../../../lib/utils/fsHelper.js", {
+ "node:fs/promises": {
+ stat: fsStatStub
+ }
+ });
+ await t.throwsAsync(exists("./test/fixtures/init/application/ui5.yaml"), {
+ message: "Some fs.stat error"
+ });
+ await t.throwsAsync(pathsExist(["src", "test"], "./foo"), {
+ message: "Some fs.stat error"
+ });
+});